// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_VALUES_H_
#define BASE_VALUES_H_

#include <stddef.h>
#include <stdint.h>

#include <array>
#include <initializer_list>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base_export.h"
#include "base/bit_cast.h"
#include "base/compiler_specific.h"
#include "base/containers/checked_iterators.h"
#include "base/containers/checked_range.h"
#include "base/containers/cxx20_erase_vector.h"
#include "base/containers/flat_map.h"
#include "base/containers/span.h"
#include "base/strings/string_piece.h"
#include "base/trace_event/base_tracing_forward.h"
#include "base/value_iterators.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/abseil-cpp/absl/types/variant.h"

namespace base {

class DictionaryValue;
class ListValue;

// The `Value` class is a variant type can hold one of the following types:
// - null
// - bool
// - int
// - double
// - string (internally UTF8-encoded)
// - binary data (i.e. a blob)
// - dictionary of string keys to `Value`s
// - list of `Value`s
//
// With the exception of binary blobs, `Value` is intended to be the C++ version
// of data types that can be represented in JSON.
//
// Warning: blob support may be removed in the future.
//
// ## Usage
//
// Do not use `Value` if a more specific type would be more appropriate.  For
// example, a function that only accepts dictionary values should have a
// `base::Value::Dict` parameter, not a `base::Value` parameter.
//
// Construction:
//
// `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
// (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
// `Value::Dict`, and `Value::List`.
//
// Copying:
//
// `Value` does not support C++ copy semantics to make it harder to accidentally
// copy large values. Instead, use `Clone()` to manually create a deep copy.
//
// Reading:
//
// `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
// subtype before returning the contained value. `bool`, `int`, `double` are
// returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
// are returned by reference.
//
// `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
// the `Value` does not have the correct subtype; otherwise, returns the value
// wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
// (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
//
// Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
// when the subtype is `Value::Type::INT`. In that case, the stored value is
// coerced to a double before being returned.
//
// Assignment:
//
// It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
// Instead, wrap the underlying type in `Value` before assigning.
//
// ## Dictionaries and Lists
//
// `Value` provides the `Value::Dict` and `Value::List` container types for
// working with dictionaries and lists of values respectively, rather than
// exposing the underlying container types directly. This allows the types to
// provide convenient helpers for dictionaries and lists, as well as giving
// greater flexibility for changing implementation details in the future.
//
// Both container types support enough STL-isms to be usable in range-based for
// loops and generic operations such as those from <algorithm>.
//
// Dictionaries support:
// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
//       `contains()`, `clear()`, `erase()`: Identical to the STL container
//       equivalents, with additional safety checks, e.g. iterators will
//       `CHECK()` if `end()` is dereferenced.
//
// - `Clone()`: Create a deep copy.
// - `Merge()`: Merge another dictionary into this dictionary.
// - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
//       is not present.
// - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
//       `Value` also has the correct subtype. Same return semantics as
//       `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
//       `nullptr` if the key is not present or the value has the wrong subtype.
// - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
//       of the subtypes that `Value` can hold.
// - `Remove()`: Remove the key from this dictionary, if present.
// - `Extract()`: If the key is present in the dictionary, removes the key from
//       the dictionary and transfers ownership of `Value` to the caller.
//       Otherwise, returns `absl::nullopt`.
//
// Dictionaries also support an additional set of helper methods that operate on
// "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
// and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
// intermediate nested dictionaries, separating the components of the path using
// '.' characters. For example, finding a string path on a `Value::Dict` using
// the dotted path:
//
//   "aaa.bbb.ccc"
//
// Will first look for a `Value::Type::DICT` associated with the key "aaa", then
// another `Value::Type::DICT` under the "aaa" dict associated with the
// key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
// with the key "ccc".
//
// If a path only has one component (i.e. has no dots), please use the regular,
// non-path APIs.
//
// Lists support:
// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
//       `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`:
//       Identical to the STL container equivalents, with additional safety
//       checks, e.g. `operator[]` will `CHECK()` if the index is out of range.
// - `Clone()`: Create a deep copy.
// - `Append()`: Append a value to the end of the list. Accepts `Value` or any
//       of the subtypes that `Value` can hold.
// - `Insert()`: Insert a `Value` at a specified point in the list.
// - `EraseValue()`: Erases all matching `Value`s from the list.
// - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
//       list.
//
// ## Refactoring Notes
//
// `Value` was originally implemented as a class hierarchy, with a `Value` base
// class, and a leaf class for each of the different types of `Value` subtypes.
// https://docs.google.com/document/d/1uDLu5uTRlCWePxQUEHc8yNQdEoE1BDISYdpggWEABnw
// proposed an overhaul of the `Value` API that has now largely been
// implemented, though there remains a significant amount of legacy code that is
// still being migrated as part of the code health migration.
//
// OLD WAY:
//
//   std::unique_ptr<base::Value> GetFoo() {
//     std::unique_ptr<DictionaryValue> dict;
//     dict->SetString("mykey", "foo");
//     return dict;
//   }
//
// NEW WAY:
//
//   base::Value GetFoo() {
//     base::Value::Dict dict;
//     dict.Set("mykey", "abc");
//     return base::Value(std::move(dict));
//   }
//
// To avoid losing type information with the new variant-based design, migration
// off the deprecated types should use more specific subtypes where possible:
//
// OLD WAY:
//
//   void AlwaysTakesList(std::unique_ptr<base::ListValue> list);
//   void AlwaysTakesDict(std::unique_ptr<base::DictionaryValue> dict);
//
// DEPRECATED (PREVIOUS) WAY:
//
//   void AlwaysTakesList(std::vector<base::Value> list);
//   void AlwaysTakesListAlternative1(base::Value::ConstListView list);
//   void AlwaysTakesListAlternative2(base::Value::ListView& list);
//   void AlwaysTakesListAlterantive3(base::Value::ListStorage);
//   void AlwaysTakesDict(base::flat_map<std::string, base::Value> dict);
//   void AlwaysTakesDictAlternative(base::Value::DictStorage);
//
// NEW WAY:
//
//   void AlwaysTakesList(base::Value::List list);
//   void AlwaysTakesDict(base::Value::Dict dict);
//
// Migrating code may require conversions on API boundaries. If something seems
// awkward/inefficient, please reach out to #code-health-rotation on Slack for
// consultation: it is entirely possible that certain classes of APIs may be
// missing due to an unrealized need.
class BASE_EXPORT GSL_OWNER Value {
 public:
  using BlobStorage = std::vector<uint8_t>;

  using DeprecatedListStorage = std::vector<Value>;
  using DeprecatedDictStorage = flat_map<std::string, Value>;
  // TODO(https://crbug.com/1291666): Make these private.
  using ListStorage = DeprecatedListStorage;
  using DictStorage = DeprecatedDictStorage;

  // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is
  // due to legacy reasons, and should be removed once no caller relies on
  // stability of pointers anymore.
  using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>;

  using DeprecatedListView = CheckedContiguousRange<ListStorage>;
  using DeprecatedConstListView = CheckedContiguousConstRange<ListStorage>;
  // TODO(https://crbug.com/1291666): Make these private.
  using ListView = DeprecatedListView;
  using ConstListView = DeprecatedConstListView;

  class Dict;
  class List;

  enum class Type : unsigned char {
    NONE = 0,
    BOOLEAN,
    INTEGER,
    DOUBLE,
    STRING,
    BINARY,
    DICT,
    // TODO(https://crbug.com/1291670): Deprecated and will be removed.
    DICTIONARY = DICT,
    LIST,
    // Note: Do not add more types. See the file-level comment above for why.
  };

  // Adaptors for converting from the old way to the new way and vice versa.
  static Value FromUniquePtrValue(std::unique_ptr<Value> val);
  static std::unique_ptr<Value> ToUniquePtrValue(Value val);
  static const DictionaryValue& AsDictionaryValue(const Value& val);
  static const ListValue& AsListValue(const Value& val);

  Value() noexcept;

  Value(Value&&) noexcept;
  Value& operator=(Value&&) noexcept;

  // Deleted to prevent accidental copying.
  Value(const Value&) = delete;
  Value& operator=(const Value&) = delete;

  // Creates a deep copy of this value.
  Value Clone() const;

  // Creates a `Value` of `type`. The data of the corresponding type will be
  // default constructed.
  explicit Value(Type type);

  // Constructor for `Value::Type::BOOLEAN`.
  explicit Value(bool value);

  // Prevent pointers from implicitly converting to bool. Another way to write
  // this would be to template the bool constructor and use SFINAE to only allow
  // use if `std::is_same_v<T, bool>` is true, but this has surprising behavior
  // with range-based for loops over a `std::vector<bool>` (which will
  // unintuitively match the int overload instead).
  //
  // The `const` is load-bearing; otherwise, a `char*` argument would prefer the
  // deleted overload due to requiring a qualification conversion.
  template <typename T>
  explicit Value(const T*) = delete;

  // Constructor for `Value::Type::INT`.
  explicit Value(int value);

  // Constructor for `Value::Type::DOUBLE`.
  explicit Value(double value);

  // Constructors for `Value::Type::STRING`.
  explicit Value(StringPiece value);
  explicit Value(StringPiece16 value);
  // `char*` and `char16_t*` are needed to provide a more specific overload than
  // the deleted `const T*` overload above.
  explicit Value(const char* value);
  explicit Value(const char16_t* value);
  // `std::string&&` allows for efficient move construction.
  explicit Value(std::string&& value) noexcept;

  // Constructors for `Value::Type::BINARY`.
  explicit Value(const std::vector<char>& value);
  explicit Value(base::span<const uint8_t> value);
  explicit Value(BlobStorage&& value) noexcept;

  // Constructor for `Value::Type::DICT`.
  explicit Value(Dict&& value) noexcept;

  // Constructor for `Value::Type::LIST`.
  explicit Value(List&& value) noexcept;

  // DEPRECATED: prefer `Value(Dict&&)`.
  explicit Value(const DictStorage& value);
  explicit Value(DictStorage&& value);

  // DEPRECATED: prefer `Value(List&&)`.
  explicit Value(span<const Value> value);
  explicit Value(ListStorage&& value) noexcept;

  ~Value();

  // Returns the name for a given `type`.
  static const char* GetTypeName(Type type);

  // Returns the type of the value stored by the current Value object.
  Type type() const { return static_cast<Type>(data_.index()); }

  // Returns true if the current object represents a given type.
  bool is_none() const { return type() == Type::NONE; }
  bool is_bool() const { return type() == Type::BOOLEAN; }
  bool is_int() const { return type() == Type::INTEGER; }
  bool is_double() const { return type() == Type::DOUBLE; }
  bool is_string() const { return type() == Type::STRING; }
  bool is_blob() const { return type() == Type::BINARY; }
  bool is_dict() const { return type() == Type::DICT; }
  bool is_list() const { return type() == Type::LIST; }

  // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
  // otherwise. `bool`, `int`, and `double` are returned in a wrapped
  // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
  // pointer.
  absl::optional<bool> GetIfBool() const;
  absl::optional<int> GetIfInt() const;
  // Returns a non-null value for both `Value::Type::DOUBLE` and
  // `Value::Type::INT`, converting the latter to a double.
  absl::optional<double> GetIfDouble() const;
  const std::string* GetIfString() const;
  std::string* GetIfString();
  const BlobStorage* GetIfBlob() const;
  const Dict* GetIfDict() const;
  Dict* GetIfDict();
  const List* GetIfList() const;
  List* GetIfList();

  // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
  // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
  // `Value::Dict`, and `Value::List` are returned by reference.
  bool GetBool() const;
  int GetInt() const;
  // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
  // converting the latter to a double.
  double GetDouble() const;
  const std::string& GetString() const;
  std::string& GetString();
  const BlobStorage& GetBlob() const;
  const Dict& GetDict() const;
  Dict& GetDict();
  const List& GetList() const;
  List& GetList();

  // Represents a dictionary of string keys to Values.
  class BASE_EXPORT GSL_OWNER Dict {
   public:
    using iterator = detail::dict_iterator;
    using const_iterator = detail::const_dict_iterator;

    Dict();

    Dict(Dict&&) noexcept;
    Dict& operator=(Dict&&) noexcept;

    // Deleted to prevent accidental copying.
    Dict(const Dict&) = delete;
    Dict& operator=(const Dict&) = delete;

    ~Dict();

    // TODO(dcheng): Probably need to allow construction from a pair of
    // iterators for now due to the prevalence of DictStorage.

    // Returns true if there are no entries in this dictionary and false
    // otherwise.
    bool empty() const;

    // Returns the number of entries in this dictionary.
    size_t size() const;

    // Returns an iterator to the first entry in this dictionary.
    iterator begin();
    const_iterator begin() const;
    const_iterator cbegin() const;

    // Returns an iterator following the last entry in this dictionary. May not
    // be dereferenced.
    iterator end();
    const_iterator end() const;
    const_iterator cend() const;

    // Returns true if `key` is an entry in this dictionary.
    bool contains(base::StringPiece key) const;

    // Removes all entries from this dictionary.
    void clear();

    // Removes the entry referenced by `pos` in this dictionary and returns an
    // iterator to the entry following the removed entry.
    iterator erase(iterator pos);
    iterator erase(const_iterator pos);

    // Creates a deep copy of this dictionary.
    Dict Clone() const;

    // Merges the entries from `dict` into this dictionary. If an entry with the
    // same key exists in this dictionary and `dict`:
    // - if both entries are dictionaries, they will be recursively merged
    // - otherwise, the already-existing entry in this dictionary will be
    //   overwritten with the entry from `dict`.
    void Merge(const Dict& dict);

    // Finds the entry corresponding to `key` in this dictionary. Returns
    // nullptr if there is no such entry.
    const Value* Find(StringPiece key) const;
    Value* Find(StringPiece key);

    // Similar to `Find()` above, but returns `absl::nullopt`/`nullptr` if the
    // type of the entry does not match. `bool`, `int`, and `double` are
    // returned in a wrapped `absl::optional`; blobs, `Value::Dict`, and
    // `Value::List` are returned by pointer.
    absl::optional<bool> FindBool(StringPiece key) const;
    absl::optional<int> FindInt(StringPiece key) const;
    // Returns a non-null value for both `Value::Type::DOUBLE` and
    // `Value::Type::INT`, converting the latter to a double.
    absl::optional<double> FindDouble(StringPiece key) const;
    const std::string* FindString(StringPiece key) const;
    std::string* FindString(StringPiece key);
    const BlobStorage* FindBlob(StringPiece key) const;
    const Dict* FindDict(StringPiece key) const;
    Dict* FindDict(StringPiece key);
    const List* FindList(StringPiece key) const;
    List* FindList(StringPiece key);

    // Sets an entry with `key` and `value` in this dictionary, overwriting any
    // existing entry with the same `key`. Returns a pointer to the set `value`.
    Value* Set(StringPiece key, Value&& value);
    Value* Set(StringPiece key, bool value);
    template <typename T>
    Value* Set(StringPiece, const T*) = delete;
    Value* Set(StringPiece key, int value);
    Value* Set(StringPiece key, double value);
    Value* Set(StringPiece key, StringPiece value);
    Value* Set(StringPiece key, StringPiece16 value);
    Value* Set(StringPiece key, const char* value);
    Value* Set(StringPiece key, const char16_t* value);
    Value* Set(StringPiece key, std::string&& value);
    Value* Set(StringPiece key, BlobStorage&& value);
    Value* Set(StringPiece key, Dict&& value);
    Value* Set(StringPiece key, List&& value);

    // Removes the entry corresponding to `key` from this dictionary. Returns
    // true if an entry was removed or false otherwise.
    bool Remove(StringPiece key);

    // Similar to `Remove()`, but returns the value corresponding to the removed
    // entry or `absl::nullopt` otherwise.
    absl::optional<Value> Extract(StringPiece key);

    // Equivalent to the above methods but operating on paths instead of keys.
    // A path is shorthand syntax for referring to a key nested inside
    // intermediate dictionaries, with components delimited by ".". Paths may
    // not be empty.
    //
    // Prefer the non-path methods above when possible. Paths that have only one
    // component (i.e. no dots in the path) should never use the path-based
    // methods.
    //
    // Originally, the path-based APIs were the only way of specifying a key, so
    // there are likely to be many legacy (and unnecessary) uses of the path
    // APIs that do not actually require traversing nested dictionaries.
    const Value* FindByDottedPath(StringPiece path) const;
    Value* FindByDottedPath(StringPiece path);

    absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
    absl::optional<int> FindIntByDottedPath(StringPiece path) const;
    // Returns a non-null value for both `Value::Type::DOUBLE` and
    // `Value::Type::INT`, converting the latter to a double.
    absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
    const std::string* FindStringByDottedPath(StringPiece path) const;
    std::string* FindStringByDottedPath(StringPiece path);
    const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
    const Dict* FindDictByDottedPath(StringPiece path) const;
    Dict* FindDictByDottedPath(StringPiece path);
    const List* FindListByDottedPath(StringPiece path) const;
    List* FindListByDottedPath(StringPiece path);

    // Creates a new entry with a dictionary for any non-last component that is
    // missing an entry while performing the path traversal. Will fail if any
    // non-last component of the path refers to an already-existing entry that
    // is not a dictionary. Returns `nullptr` on failure.
    Value* SetByDottedPath(StringPiece path, Value&& value);
    Value* SetByDottedPath(StringPiece path, bool value);
    template <typename T>
    Value* SetByDottedPath(StringPiece, const T*) = delete;
    Value* SetByDottedPath(StringPiece path, int value);
    Value* SetByDottedPath(StringPiece path, double value);
    Value* SetByDottedPath(StringPiece path, StringPiece value);
    Value* SetByDottedPath(StringPiece path, StringPiece16 value);
    Value* SetByDottedPath(StringPiece path, const char* value);
    Value* SetByDottedPath(StringPiece path, const char16_t* value);
    Value* SetByDottedPath(StringPiece path, std::string&& value);
    Value* SetByDottedPath(StringPiece path, BlobStorage&& value);
    Value* SetByDottedPath(StringPiece path, Dict&& value);
    Value* SetByDottedPath(StringPiece path, List&& value);

    bool RemoveByDottedPath(StringPiece path);

    absl::optional<Value> ExtractByDottedPath(StringPiece path);

    // Serializes to a string for logging and debug purposes.
    std::string DebugString() const;

   private:
    BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs);
    BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs);
    BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs);
    BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
    BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
    BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);

    // For legacy access to the internal storage type.
    friend Value;

    explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);

    flat_map<std::string, std::unique_ptr<Value>> storage_;
  };

  // Represents a list of Values.
  class BASE_EXPORT GSL_OWNER List {
   public:
    using iterator = CheckedContiguousIterator<Value>;
    using const_iterator = CheckedContiguousConstIterator<Value>;

    List();

    List(List&&) noexcept;
    List& operator=(List&&) noexcept;

    // Deleted to prevent accidental copying.
    List(const List&) = delete;
    List& operator=(const List&) = delete;

    ~List();

    // TODO(dcheng): Probably need to allow construction from a pair of
    // iterators for now due to the prevalence of ListStorage now.

    // Returns true if there are no values in this list and false otherwise.
    bool empty() const;

    // Returns the number of values in this list.
    size_t size() const;

    // Returns an iterator to the first value in this list.
    iterator begin();
    const_iterator begin() const;
    const_iterator cbegin() const;

    // Returns an iterator following the last value in this list. May not be
    // dereferenced.
    iterator end();
    const_iterator end() const;
    const_iterator cend() const;

    // Returns a reference to the first value in the container. Fails with
    // `CHECK()` if the list is empty.
    const Value& front() const;
    Value& front();

    // Returns a reference to the last value in the container. Fails with
    // `CHECK()` if the list is empty.
    const Value& back() const;
    Value& back();

    // Increase the capacity of the backing container, but does not change
    // the size. Assume all existing iterators will be invalidated.
    void reserve(size_t capacity);

    // Returns a reference to the value at `index` in this list. Fails with a
    // `CHECK()` if `index >= size()`.
    const Value& operator[](size_t index) const;
    Value& operator[](size_t index);

    // Removes all value from this list.
    void clear();

    // Removes the value referenced by `pos` in this list and returns an
    // iterator to the value following the removed value.
    iterator erase(iterator pos);
    const_iterator erase(const_iterator pos);

    // Creates a deep copy of this dictionary.
    List Clone() const;

    // Appends `value` to the end of this list.
    void Append(Value&& value);
    void Append(bool value);
    template <typename T>
    void Append(const T*) = delete;
    void Append(int value);
    void Append(double value);
    void Append(StringPiece value);
    void Append(StringPiece16 value);
    void Append(const char* value);
    void Append(const char16_t* value);
    void Append(std::string&& value);
    void Append(BlobStorage&& value);
    void Append(Dict&& value);
    void Append(List&& value);

    // Inserts `value` before `pos` in this list. Returns an iterator to the
    // inserted value.
    // TODO(dcheng): Should this provide the same set of overloads that Append()
    // does?
    iterator Insert(const_iterator pos, Value&& value);

    // Erases all values equal to `value` from this list.
    size_t EraseValue(const Value& value);

    // Erases all values for which `predicate` evaluates to true from this list.
    template <typename Predicate>
    size_t EraseIf(Predicate predicate) {
      return base::EraseIf(storage_, predicate);
    }

    // Serializes to a string for logging and debug purposes.
    std::string DebugString() const;

   private:
    BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
    BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
    BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
    BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
    BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
    BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);

    // For legacy access to the internal storage type.
    friend Value;

    explicit List(const std::vector<Value>& storage);

    std::vector<Value> storage_;
  };

  // ===== DEPRECATED methods that require `type() == Type::LIST` =====

  // Returns the Values in a list as a view. The mutable overload allows for
  // modification of the underlying values, but does not allow changing the
  // structure of the list. If this is desired, use `TakeListDeprecated()`,
  // perform the operations, and return the list back to the Value via move
  // assignment.
  //
  // DEPRECATED: prefer direct use `base::Value::List` where possible, or
  // `GetList()` otherwise.
  DeprecatedListView GetListDeprecated();
  DeprecatedConstListView GetListDeprecated() const;

  // Transfers ownership of the underlying list to the caller. Subsequent
  // calls to `GetListDeprecated()` will return an empty list.
  //
  // DEPRECATED: prefer direct use of `base::Value::List` where possible, or
  // `std::move(value.GetList())` otherwise.
  DeprecatedListStorage TakeListDeprecated() &&;

  // Appends `value` to the end of the list.
  //
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(Value&& value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(bool value);
  template <typename T>
  void Append(const T* ptr) = delete;
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(int value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(double value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(StringPiece value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(StringPiece16 value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(const char* value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(const char16_t* value);
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(std::string&& value);

  // Inserts `value` before `pos`.
  //
  // DEPRECATED: prefer `Value::List::Insert()`.
  CheckedContiguousIterator<Value> Insert(
      CheckedContiguousConstIterator<Value> pos,
      Value&& value);

  // Erases the Value pointed to by `iter`. Returns false if `iter` is out of
  // bounds.
  //
  // DEPRECATED: prefer `Value::List::erase(iter)`.
  bool EraseListIter(CheckedContiguousConstIterator<Value> iter);

  // Erases all Values that compare equal to `val`. Returns the number of
  // deleted Values.
  //
  // DEPRECATED: prefer `Value::List::EraseValue(val)`.
  size_t EraseListValue(const Value& val);

  // Erases all Values for which `pred` returns true. Returns the number of
  // deleted Values.
  //
  // DEPRECATED: prefer `Value::List::EraseIf(pred)`.
  template <typename Predicate>
  size_t EraseListValueIf(Predicate pred) {
    return base::EraseIf(list(), pred);
  }

  // Erases all Values from the list.
  //
  // DEPRECATED: prefer `Value::List::clear()`.
  void ClearList();

  // ===== DEPRECATED methods that require `type() == Type::DICT` =====

  // `FindKey` looks up `key` in the underlying dictionary. If found, it returns
  // a pointer to the element. Otherwise it returns nullptr.
  //
  // DEPRECATED: prefer `Value::Dict::Find()`.
  Value* FindKey(StringPiece key);
  const Value* FindKey(StringPiece key) const;

  // `FindKeyOfType` is similar to `FindKey`, but it also requires the found
  // value to have type `type`. If no type is found, or the found value is of a
  // different type nullptr is returned.
  //
  // DEPRECATED: prefer `Value::Dict::FindBool()`, `Value::Dict::FindInt()`, et
  // cetera.
  Value* FindKeyOfType(StringPiece key, Type type);
  const Value* FindKeyOfType(StringPiece key, Type type) const;

  // These are convenience forms of `FindKey`. They return `absl::nullopt` or
  // `nullptr` if the value is not found or doesn't have the type specified in
  // the function's name.
  //
  // DEPRECATED: prefer `Value::Dict::FindBool()`.
  absl::optional<bool> FindBoolKey(StringPiece key) const;
  // DEPRECATED: prefer `Value::Dict::FindInt()`.
  absl::optional<int> FindIntKey(StringPiece key) const;
  // Returns a non-null value for both `Value::Type::DOUBLE` and
  // `Value::Type::INT`, converting the latter to a double.
  //
  // DEPRECATED: prefer `Value::Dict::FindDouble()`.
  absl::optional<double> FindDoubleKey(StringPiece key) const;
  // DEPRECATED: prefer `Value::Dict::FindString()`.
  const std::string* FindStringKey(StringPiece key) const;
  std::string* FindStringKey(StringPiece key);
  // DEPRECATED: prefer `Value::Dict::FindBlob()`.
  const BlobStorage* FindBlobKey(StringPiece key) const;
  // DEPRECATED: prefer `Value::Dict::FindDict()`.
  const Value* FindDictKey(StringPiece key) const;
  Value* FindDictKey(StringPiece key);
  // DEPRECATED: prefer `Value::Dict::FindList()`.
  const Value* FindListKey(StringPiece key) const;
  Value* FindListKey(StringPiece key);

  // `SetKey` looks up `key` in the underlying dictionary and sets the mapped
  // value to `value`. If `key` could not be found, a new element is inserted.
  // A pointer to the modified item is returned.
  //
  // Note: Prefer `Set<Type>Key()` if the input is not already a `Value`.
  //
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetKey(StringPiece key, Value&& value);

  // `Set`Type>Key` looks up `key` in the underlying dictionary and associates a
  // corresponding Value() constructed from the second parameter. Compared to
  // `SetKey()`, this avoids un-necessary temporary `Value()` creation, as well
  // ambiguities in the value type.
  //
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetBoolKey(StringPiece key, bool val);
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetIntKey(StringPiece key, int val);
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetDoubleKey(StringPiece key, double val);
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetStringKey(StringPiece key, StringPiece val);
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetStringKey(StringPiece key, StringPiece16 val);
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetStringKey(StringPiece key, const char* val);
  // DEPRECATED: Prefer `Value::Dict::Set()`.
  Value* SetStringKey(StringPiece key, std::string&& val);

  // This attempts to remove the value associated with `key`. In case of
  // failure, e.g. the key does not exist, false is returned and the underlying
  // dictionary is not changed. In case of success, `key` is deleted from the
  // dictionary and the method returns true.
  //
  // Deprecated: Prefer `Value::Dict::Remove()`.
  bool RemoveKey(StringPiece key);

  // This attempts to extract the value associated with `key`. In case of
  // failure, e.g. the key does not exist, nullopt is returned and the
  // underlying dictionary is not changed. In case of success, `key` is deleted
  // from the dictionary and the method returns the extracted Value.
  //
  // DEPRECATED: Prefer `Value::Dict::Extract()`.
  absl::optional<Value> ExtractKey(StringPiece key);

  // Searches a hierarchy of dictionary values for a given value. If a path
  // of dictionaries exist, returns the item at that path. If any of the path
  // components do not exist or if any but the last path components are not
  // dictionaries, returns nullptr. The type of the leaf Value is not checked.
  //
  // This version takes a StringPiece for the path, using dots as separators.
  //
  // DEPRECATED: Prefer `Value::Dict::FindByDottedPath()`.
  Value* FindPath(StringPiece path);
  const Value* FindPath(StringPiece path) const;

  // There are also deprecated versions that take the path parameter
  // as either a std::initializer_list<StringPiece> or a
  // span<const StringPiece>. The latter is useful to use a
  // std::vector<std::string> as a parameter but creates huge dynamic
  // allocations and should be avoided!
  // Note: If there is only one component in the path, use `FindKey()` instead.
  //
  // Example:
  //   std::vector<StringPiece> components = ...
  //   auto* found = FindPath(components);
  //
  // DEPRECATED: These are not common, and there is no currently planned
  // replacement.
  Value* FindPath(std::initializer_list<StringPiece> path);
  Value* FindPath(span<const StringPiece> path);
  const Value* FindPath(std::initializer_list<StringPiece> path) const;
  const Value* FindPath(span<const StringPiece> path) const;

  // Like FindPath() but will only return the value if the leaf Value type
  // matches the given type. Will return nullptr otherwise.
  // Note: Prefer `Find<Type>Path()` for simple values.
  //
  // Note: If there is only one component in the path, use `FindKeyOfType()`
  // instead for slightly better performance.
  //
  // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`,
  // `Value::Dict::FindIntByDottedPath()`, et cetera.
  Value* FindPathOfType(StringPiece path, Type type);
  const Value* FindPathOfType(StringPiece path, Type type) const;

  // Convenience accessors used when the expected type of a value is known.
  // Similar to Find<Type>Key() but accepts paths instead of keys.
  //
  // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`, or
  // `Value::Dict::FindBool()` if the path only has one component, i.e. has no
  // dots.
  absl::optional<bool> FindBoolPath(StringPiece path) const;
  // DEPRECATED: Use `Value::Dict::FindIntByDottedPath()`, or
  // `Value::Dict::FindInt()` if the path only has one component, i.e. has no
  // dots.
  absl::optional<int> FindIntPath(StringPiece path) const;
  // DEPRECATED: Use `Value::Dict::FindDoubleByDottedPath()`, or
  // `Value::Dict::FindDouble()` if the path only has one component, i.e. has no
  // dots.
  absl::optional<double> FindDoublePath(StringPiece path) const;
  // DEPRECATED: Use `Value::Dict::FindStringByDottedPath()`, or
  // `Value::Dict::FindString()` if the path only has one component, i.e. has no
  // dots.
  const std::string* FindStringPath(StringPiece path) const;
  std::string* FindStringPath(StringPiece path);
  // DEPRECATED: Use `Value::Dict::FindBlobByDottedPath()`, or
  // `Value::Dict::FindBlob()` if the path only has one component, i.e. has no
  // dots.
  const BlobStorage* FindBlobPath(StringPiece path) const;
  // DEPRECATED: Use `Value::Dict::FindDictByDottedPath()`, or
  // `Value::Dict::FindDict()` if the path only has one component, i.e. has no
  // dots.
  Value* FindDictPath(StringPiece path);
  const Value* FindDictPath(StringPiece path) const;
  // DEPRECATED: Use `Value::Dict::FindListByDottedPath()`, or
  // `Value::Dict::FindList()` if the path only has one component, i.e. has no
  // dots.
  Value* FindListPath(StringPiece path);
  const Value* FindListPath(StringPiece path) const;

  // The following forms are deprecated too, use the ones that take the path
  // as a single StringPiece instead.
  //
  // DEPRECATED: These are not common, and there is no currently planned
  // replacement.
  Value* FindPathOfType(std::initializer_list<StringPiece> path, Type type);
  Value* FindPathOfType(span<const StringPiece> path, Type type);
  const Value* FindPathOfType(std::initializer_list<StringPiece> path,
                              Type type) const;
  const Value* FindPathOfType(span<const StringPiece> path, Type type) const;

  // Sets the given path, expanding and creating dictionary keys as necessary.
  //
  // If the current value is not a dictionary, the function returns nullptr. If
  // path components do not exist, they will be created. If any but the last
  // components matches a value that is not a dictionary, the function will fail
  // (it will not overwrite the value) and return nullptr. The last path
  // component will be unconditionally overwritten if it exists, and created if
  // it doesn't.
  //
  // Note: If there is only one component in the path, use `SetKey()` instead.
  // Note: Using `Set<Type>Path()` might be more convenient and efficient.
  //
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetPath(StringPiece path, Value&& value);

  // These setters are more convenient and efficient than the corresponding
  // SetPath(...) call.
  //
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetBoolPath(StringPiece path, bool value);
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetIntPath(StringPiece path, int value);
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetDoublePath(StringPiece path, double value);
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetStringPath(StringPiece path, StringPiece value);
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetStringPath(StringPiece path, const char* value);
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetStringPath(StringPiece path, std::string&& value);
  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetStringPath(StringPiece path, StringPiece16 value);

  // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
  Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
  Value* SetPath(span<const StringPiece> path, Value&& value);

  // Tries to remove a Value at the given path.
  //
  // If the current value is not a dictionary or any path component does not
  // exist, this operation fails, leaves underlying Values untouched and returns
  // `false`. In case intermediate dictionaries become empty as a result of this
  // path removal, they will be removed as well.
  // Note: If there is only one component in the path, use `RemoveKey()`
  // instead.
  //
  // DEPRECATED: Use `Value::Dict::RemoveByDottedPath()`.
  bool RemovePath(StringPiece path);

  // Tries to extract a Value at the given path.
  //
  // If the current value is not a dictionary or any path component does not
  // exist, this operation fails, leaves underlying Values untouched and returns
  // nullopt. In case intermediate dictionaries become empty as a result of this
  // path removal, they will be removed as well. Returns the extracted value on
  // success.
  // Note: If there is only one component in the path, use `ExtractKey()`
  // instead.
  //
  // DEPRECATED: Use `Value::Dict::ExtractByDottedPath()`.
  absl::optional<Value> ExtractPath(StringPiece path);

  using dict_iterator_proxy = detail::dict_iterator_proxy;
  using const_dict_iterator_proxy = detail::const_dict_iterator_proxy;

  // `DictItems` returns a proxy object that exposes iterators to the underlying
  // dictionary. These are intended for iteration over all items in the
  // dictionary and are compatible with for-each loops and standard library
  // algorithms.
  //
  // Unlike with std::map, a range-for over the non-const version of
  // `DictItems()` will range over items of type
  // `pair<const std::string&, Value&>`, so code of the form
  //   for (auto kv : my_value.DictItems())
  //     Mutate(kv.second);
  // will actually alter `my_value` in place (if it isn't const).
  //
  // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
  // instead.
  dict_iterator_proxy DictItems();
  const_dict_iterator_proxy DictItems() const;

  // Transfers ownership of the underlying dict to the caller. Subsequent
  // calls to DictItems() will return an empty dict.
  //
  // DEPRECATED: prefer direct use of `base::Value::Dict` where possible, or
  // `std::move(value.GetDict())` otherwise.
  DeprecatedDictStorage TakeDictDeprecated() &&;

  // DEPRECATED: prefer `Value::Dict::size()`.
  size_t DictSize() const;

  // DEPRECATED: prefer `Value::Dict::empty()`.
  bool DictEmpty() const;

  // DEPRECATED: prefer `Value::Dict::clear()`.
  void DictClear();

  // Merge `dictionary` into this value. This is done recursively, i.e. any
  // sub-dictionaries will be merged as well. In case of key collisions, the
  // passed in dictionary takes precedence and data already present will be
  // replaced. Values within `dictionary` are deep-copied, so `dictionary` may
  // be freed any time after this call.
  // Note: This requires that `type()` and `dictionary->type()` is
  // Type::DICT.
  //
  // DEPRECATED: prefer `Value::Dict::Merge()`.
  void MergeDictionary(const Value* dictionary);

  // These methods allow the convenient retrieval of the contents of the Value.
  // If the current object can be converted into the given type, the value is
  // returned through the `out_value` parameter and true is returned;
  // otherwise, false is returned and `out_value` is unchanged.
  // ListValue::From is the equivalent for std::unique_ptr conversions.
  //
  // DEPRECATED: prefer direct use `base::Value::List` where possible, or
  // `GetIfList()` otherwise.
  bool GetAsList(ListValue** out_value);
  bool GetAsList(const ListValue** out_value) const;
  // DictionaryValue::From is the equivalent for std::unique_ptr conversions.
  //
  // DEPRECATED: prefer direct use `base::Value::Dict` where possible, or
  // `GetIfDict()` otherwise.
  bool GetAsDictionary(DictionaryValue** out_value);
  bool GetAsDictionary(const DictionaryValue** out_value) const;
  // Note: Do not add more types. See the file-level comment above for why.

  // This creates a deep copy of the entire Value tree, and returns a pointer
  // to the copy. The caller gets ownership of the copy, of course.
  // Subclasses return their own type directly in their overrides;
  // this works because C++ supports covariant return types.
  // TODO(crbug.com/646113): Delete this and migrate callsites.
  //
  // DEPRECATED: prefer `Value::Clone()`.
  std::unique_ptr<Value> CreateDeepCopy() const;

  // Comparison operators so that Values can easily be used with standard
  // library algorithms and associative containers.
  BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
  BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs);
  BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs);
  BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs);
  BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
  BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);

  // Compares if two Value objects have equal contents.
  // DEPRECATED, use `operator==(const Value& lhs, const Value& rhs)` instead.
  // TODO(crbug.com/646113): Delete this and migrate callsites.
  //
  // DEPRECATED: prefer direct use of the equality operator instead.
  bool Equals(const Value* other) const;

  // Estimates dynamic memory usage. Requires tracing support
  // (enable_base_tracing gn flag), otherwise always returns 0. See
  // base/trace_event/memory_usage_estimator.h for more info.
  size_t EstimateMemoryUsage() const;

  // Serializes to a string for logging and debug purposes.
  std::string DebugString() const;

#if BUILDFLAG(ENABLE_BASE_TRACING)
  // Write this object into a trace.
  void WriteIntoTrace(perfetto::TracedValue) const;
#endif  // BUILDFLAG(ENABLE_BASE_TRACING)

  template <typename Visitor>
  auto Visit(Visitor&& visitor) const {
    return absl::visit(std::forward<Visitor>(visitor), data_);
  }

 protected:
  // Checked convenience accessors for dict and list.
  const LegacyDictStorage& dict() const { return GetDict().storage_; }
  LegacyDictStorage& dict() { return GetDict().storage_; }
  const ListStorage& list() const { return GetList().storage_; }
  ListStorage& list() { return GetList().storage_; }

  // Internal constructors, allowing the simplify the implementation of Clone().
  explicit Value(const LegacyDictStorage& storage);
  explicit Value(LegacyDictStorage&& storage) noexcept;

 private:
  // For access to DoubleStorage.
  friend class ValueView;

  // Special case for doubles, which are aligned to 8 bytes on some
  // 32-bit architectures. In this case, a simple declaration as a
  // double member would make the whole union 8 byte-aligned, which
  // would also force 4 bytes of wasted padding space before it in
  // the Value layout.
  //
  // To override this, store the value as an array of 32-bit integers, and
  // perform the appropriate bit casts when reading / writing to it.
  class DoubleStorage {
   public:
    explicit DoubleStorage(double v);
    DoubleStorage(const DoubleStorage&) = default;
    DoubleStorage& operator=(const DoubleStorage&) = default;

    // Provide an implicit conversion to double to simplify the use of visitors
    // with `Value::Visit()`. Otherwise, visitors would need a branch for
    // handling `DoubleStorage` like:
    //
    //   value.Visit([] (const auto& member) {
    //     using T = std::decay_t<decltype(member)>;
    //     if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
    //       SomeFunction(double{member});
    //     } else {
    //       SomeFunction(member);
    //     }
    //   });
    operator double() const { return base::bit_cast<double>(v_); }

   private:
    friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
      return double{lhs} == double{rhs};
    }

    friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
      return !(lhs == rhs);
    }

    friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
      return double{lhs} < double{rhs};
    }

    friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
      return rhs < lhs;
    }

    friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
      return !(rhs < lhs);
    }

    friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
      return !(lhs < rhs);
    }

    alignas(4) std::array<char, sizeof(double)> v_;
  };

  // Internal constructors, allowing the simplify the implementation of Clone().
  explicit Value(absl::monostate);
  explicit Value(DoubleStorage storage);

  absl::variant<absl::monostate,
                bool,
                int,
                DoubleStorage,
                std::string,
                BlobStorage,
                Dict,
                List>
      data_;
};

// DictionaryValue provides a key-value dictionary with (optional) "path"
// parsing for recursive access; see the comment at the top of the file. Keys
// are std::string's and should be UTF-8 encoded.
//
// DEPRECATED: prefer `Value::Dict`.
class BASE_EXPORT DictionaryValue : public Value {
 public:
  // Returns `value` if it is a dictionary, nullptr otherwise.
  static std::unique_ptr<DictionaryValue> From(std::unique_ptr<Value> value);

  DictionaryValue();
  explicit DictionaryValue(const LegacyDictStorage& in_dict);
  explicit DictionaryValue(LegacyDictStorage&& in_dict) noexcept;

  // Returns true if the current dictionary has a value for the given key.
  //
  // DEPRECATED: prefer `Value::Dict::contains()`.
  bool HasKey(StringPiece key) const;

  // Sets the Value associated with the given path starting from this object.
  // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
  // into the next DictionaryValue down.  Obviously, "." can't be used
  // within a key, but there are no other restrictions on keys.
  // If the key at any step of the way doesn't exist, or exists but isn't
  // a DictionaryValue, a new DictionaryValue will be created and attached
  // to the path in that location. `in_value` must be non-null.
  // Returns a pointer to the inserted value.
  //
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  Value* Set(StringPiece path, std::unique_ptr<Value> in_value);

  // Convenience forms of Set().  These methods will replace any existing
  // value at that path, even if it has a different type.
  //
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  Value* SetBoolean(StringPiece path, bool in_value);
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  Value* SetInteger(StringPiece path, int in_value);
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  Value* SetDouble(StringPiece path, double in_value);
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  Value* SetString(StringPiece path, StringPiece in_value);
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  Value* SetString(StringPiece path, const std::u16string& in_value);
  // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
  // otherwise.
  ListValue* SetList(StringPiece path, std::unique_ptr<ListValue> in_value);

  // Like Set(), but without special treatment of '.'.  This allows e.g. URLs to
  // be used as paths.
  //
  // DEPRECATED: prefer `Value::Dict::Set()`.
  Value* SetWithoutPathExpansion(StringPiece key,
                                 std::unique_ptr<Value> in_value);

  // Gets the Value associated with the given path starting from this object.
  // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
  // into the next DictionaryValue down.  If the path can be resolved
  // successfully, the value for the last key in the path will be returned
  // through the `out_value` parameter, and the function will return true.
  // Otherwise, it will return false and `out_value` will be untouched.
  // Note that the dictionary always owns the value that's returned.
  // `out_value` is optional and will only be set if non-NULL.
  //
  // DEPRECATED: prefer `Value::Dict::Find()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::FindByDottedPath()`
  // otherwise.
  bool Get(StringPiece path, const Value** out_value) const;
  bool Get(StringPiece path, Value** out_value);

  // These are convenience forms of `Get()`.  The value will be retrieved
  // and the return value will be true if the path is valid and the value at
  // the end of the path can be returned in the form specified.
  // `out_value` is optional and will only be set if non-NULL.
  //
  // DEPRECATED: prefer `Value::Dict::FindInt()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::FindIntByDottedPath()`
  // otherwise.
  bool GetInteger(StringPiece path, int* out_value) const;
  // DEPRECATED: prefer `Value::Dict::FindString()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
  // otherwise.
  bool GetString(StringPiece path, std::string* out_value) const;
  bool GetString(StringPiece path, std::u16string* out_value) const;
  // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
  // otherwise.
  bool GetDictionary(StringPiece path, const DictionaryValue** out_value) const;
  bool GetDictionary(StringPiece path, DictionaryValue** out_value);
  // DEPRECATED: prefer `Value::Dict::FindList()` (if the path only has one
  // component, i.e. has no dots), or `Value::Dict::FindListByDottedPath()`
  // otherwise.
  bool GetList(StringPiece path, const ListValue** out_value) const;
  bool GetList(StringPiece path, ListValue** out_value);

  // Like `Get()`, but without special treatment of '.'.  This allows e.g. URLs
  // to be used as paths.
  // DEPRECATED, use `Value::FindDictKey(key)` instead.
  bool GetDictionaryWithoutPathExpansion(
      StringPiece key,
      const DictionaryValue** out_value) const;
  // DEPRECATED, use `Value::FindDictKey(key)` instead.
  bool GetDictionaryWithoutPathExpansion(StringPiece key,
                                         DictionaryValue** out_value);
  // DEPRECATED, use `Value::FindListKey(key)` instead.
  bool GetListWithoutPathExpansion(StringPiece key,
                                   const ListValue** out_value) const;
  // DEPRECATED, use `Value::FindListKey(key)` instead.
  bool GetListWithoutPathExpansion(StringPiece key, ListValue** out_value);

  // Makes a copy of `this` but doesn't include empty dictionaries and lists in
  // the copy.  This never returns NULL, even if `this` itself is empty.
  std::unique_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const;

  // Swaps contents with the `other` dictionary.
  void Swap(DictionaryValue* other);

  // This class provides an iterator over both keys and values in the
  // dictionary.  It can't be used to modify the dictionary.
  //
  // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
  // instead.
  class BASE_EXPORT Iterator {
   public:
    explicit Iterator(const DictionaryValue& target);
    Iterator(const Iterator& other);
    ~Iterator();

    bool IsAtEnd() const { return it_ == target_.DictItems().end(); }
    void Advance() { ++it_; }

    const std::string& key() const { return it_->first; }
    const Value& value() const { return it_->second; }

   private:
    const DictionaryValue& target_;
    detail::const_dict_iterator it_;
  };

  // DEPRECATED, use `Value::Dict::Clone()` instead.
  // TODO(crbug.com/646113): Delete this and migrate callsites.
  DictionaryValue* DeepCopy() const;
  // DEPRECATED, use `Value::Dict::Clone()` instead.
  // TODO(crbug.com/646113): Delete this and migrate callsites.
  std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
};

// This type of Value represents a list of other Value values.
//
// DEPRECATED: prefer `base::Value::List`.
class BASE_EXPORT ListValue : public Value {
 public:
  using const_iterator = ListView::const_iterator;
  using iterator = ListView::iterator;

  // Returns `value` if it is a list, nullptr otherwise.
  static std::unique_ptr<ListValue> From(std::unique_ptr<Value> value);

  ListValue();
  explicit ListValue(span<const Value> in_list);
  explicit ListValue(ListStorage&& in_list) noexcept;

  // Convenience forms of `Get()`.  Modifies `out_value` (and returns true)
  // only if the index is valid and the Value at that index can be returned
  // in the specified form.
  // `out_value` is optional and will only be set if non-NULL.
  //
  // DEPRECATED: prefer `Value::List::operator[]` + `GetIfDict()`.
  bool GetDictionary(size_t index, const DictionaryValue** out_value) const;
  bool GetDictionary(size_t index, DictionaryValue** out_value);

  // Appends a Value to the end of the list.
  // DEPRECATED: prefer `Value::List::Append()`.
  using Value::Append;
  // DEPRECATED: prefer `Value::List::Append()`.
  void Append(std::unique_ptr<Value> in_value);
  // DEPRECATED: prefer `Value::List::Append()`. Provided to simplify
  // incremental migration and intentionally only defined on ListValue and not
  // Value.
  void Append(base::Value::Dict in_dict);
  void Append(base::Value::List in_list);

  // Swaps contents with the `other` list.
  //
  // DEPRECATED: prefer `base::Value::List` + `std::swap()`.
  void Swap(ListValue* other);

  // Iteration: Use a range-based for loop over `base::Value::List` directly
  // instead.
};

// Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
// serialization methods without having to clone the contents and transfer
// ownership of the clone to a `Value` wrapper object.
//
// Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
// underlying object that is passed by reference (i.e. `std::string`,
// `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
// live as long as there is a `ValueView` referencing it.
//
// While it might be nice to just use the `absl::variant` type directly, the
// need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
// `std::reference_wrapper` both support implicit construction, but C++ only
// allows at most one user-defined conversion in an implicit conversion
// sequence. If this adapter and its implicit constructors did not exist,
// callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
// `Value::List` to a function with a `ValueView` parameter.
class BASE_EXPORT GSL_POINTER ValueView {
 public:
  ValueView(bool value) : data_view_(value) {}
  ValueView(int value) : data_view_(value) {}
  ValueView(double value)
      : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
  ValueView(const std::string& value) : data_view_(value) {}
  ValueView(const Value::BlobStorage& value) : data_view_(value) {}
  ValueView(const Value::Dict& value) : data_view_(value) {}
  ValueView(const Value::List& value) : data_view_(value) {}
  ValueView(const Value& value);

  template <typename Visitor>
  auto Visit(Visitor&& visitor) const {
    return absl::visit(std::forward<Visitor>(visitor), data_view_);
  }

 private:
  using ViewType =
      absl::variant<absl::monostate,
                    bool,
                    int,
                    Value::DoubleStorage,
                    std::reference_wrapper<const std::string>,
                    std::reference_wrapper<const Value::BlobStorage>,
                    std::reference_wrapper<const Value::Dict>,
                    std::reference_wrapper<const Value::List>>;

  ViewType data_view_;
};

// This interface is implemented by classes that know how to serialize
// Value objects.
class BASE_EXPORT ValueSerializer {
 public:
  virtual ~ValueSerializer();

  virtual bool Serialize(ValueView root) = 0;
};

// This interface is implemented by classes that know how to deserialize Value
// objects.
class BASE_EXPORT ValueDeserializer {
 public:
  virtual ~ValueDeserializer();

  // This method deserializes the subclass-specific format into a Value object.
  // If the return value is non-NULL, the caller takes ownership of returned
  // Value.
  //
  // If the return value is nullptr, and if `error_code` is non-nullptr,
  // `*error_code` will be set to an integer value representing the underlying
  // error. See "enum ErrorCode" below for more detail about the integer value.
  //
  // If `error_message` is non-nullptr, it will be filled in with a formatted
  // error message including the location of the error if appropriate.
  virtual std::unique_ptr<Value> Deserialize(int* error_code,
                                             std::string* error_message) = 0;

  // The integer-valued error codes form four groups:
  //  - The value 0 means no error.
  //  - Values between 1 and 999 inclusive mean an error in the data (i.e.
  //    content). The bytes being deserialized are not in the right format.
  //  - Values 1000 and above mean an error in the metadata (i.e. context). The
  //    file could not be read, the network is down, etc.
  //  - Negative values are reserved.
  //
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum ErrorCode {
    kErrorCodeNoError = 0,
    // kErrorCodeInvalidFormat is a generic error code for "the data is not in
    // the right format". Subclasses of ValueDeserializer may return other
    // values for more specific errors.
    kErrorCodeInvalidFormat = 1,
    // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
    // range of metadata errors.
    kErrorCodeFirstMetadataError = 1000,
  };

  // The `error_code` argument can be one of the ErrorCode values, but it is
  // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
  // can define their own error code values.
  static inline bool ErrorCodeIsDataError(int error_code) {
    return (kErrorCodeInvalidFormat <= error_code) &&
           (error_code < kErrorCodeFirstMetadataError);
  }
};

// Stream operator so Values can be pretty printed by gtest.
BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
BASE_EXPORT std::ostream& operator<<(std::ostream& out,
                                     const Value::Dict& dict);
BASE_EXPORT std::ostream& operator<<(std::ostream& out,
                                     const Value::List& list);

// Hints for DictionaryValue and ListValue; otherwise, gtest tends to prefer the
// default template implementation over an upcast to Value.
BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
                                            const DictionaryValue& value) {
  return out << static_cast<const Value&>(value);
}

BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
                                            const ListValue& value) {
  return out << static_cast<const Value&>(value);
}

// Stream operator so that enum class Types can be used in log statements.
BASE_EXPORT std::ostream& operator<<(std::ostream& out,
                                     const Value::Type& type);

}  // namespace base

#endif  // BASE_VALUES_H_
