#include "base/values.h"
#include <array>
#include <cmath>
#include <memory>
#include <optional>
#include <ostream>
#include <string_view>
#include <tuple>
#include <utility>
#include "base/bit_cast.h"
#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/checked_iterators.h"
#include "base/containers/map_util.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/base_tracing.h"
#include "base/tracing_buildflags.h"
#include "base/types/to_address.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#if BUILDFLAG(ENABLE_BASE_TRACING)
#include "base/trace_event/memory_usage_estimator.h"
#endif
namespace base {
namespace {
constexpr auto kTypeNames = …;
static_assert …;
class PathSplitter { … };
std::string DebugStringImpl(ValueView value) { … }
}
class Value::CloningHelper { … };
Value Value::FromUniquePtrValue(std::unique_ptr<Value> val) { … }
std::unique_ptr<Value> Value::ToUniquePtrValue(Value val) { … }
Value::Value() noexcept = default;
Value::Value(Value&&) noexcept = default;
Value& Value::operator=(Value&&) noexcept = default;
Value::Value(Type type) { … }
Value::Value(bool value) : … { … }
Value::Value(int value) : … { … }
Value::Value(double value)
: … { … }
Value::Value(std::string_view value) : … { … }
Value::Value(std::u16string_view value) : … { … }
Value::Value(const char* value) : … { … }
Value::Value(const char16_t* value) : … { … }
Value::Value(std::string&& value) noexcept : … { … }
Value::Value(const std::vector<char>& value)
: … { … }
Value::Value(base::span<const uint8_t> value)
: … { … }
Value::Value(BlobStorage&& value) noexcept : … { … }
Value::Value(Dict&& value) noexcept : … { … }
Value::Value(List&& value) noexcept : … { … }
Value::Value(absl::monostate) { … }
Value::Value(DoubleStorage storage) : … { … }
Value::DoubleStorage::DoubleStorage(double v) : … { … }
Value Value::Clone() const { … }
Value::~Value() = default;
const char* Value::GetTypeName(Value::Type type) { … }
std::optional<bool> Value::GetIfBool() const { … }
std::optional<int> Value::GetIfInt() const { … }
std::optional<double> Value::GetIfDouble() const { … }
const std::string* Value::GetIfString() const { … }
std::string* Value::GetIfString() { … }
const Value::BlobStorage* Value::GetIfBlob() const { … }
const Value::Dict* Value::GetIfDict() const { … }
Value::Dict* Value::GetIfDict() { … }
const Value::List* Value::GetIfList() const { … }
Value::List* Value::GetIfList() { … }
bool Value::GetBool() const { … }
int Value::GetInt() const { … }
double Value::GetDouble() const { … }
const std::string& Value::GetString() const { … }
std::string& Value::GetString() { … }
const Value::BlobStorage& Value::GetBlob() const { … }
const Value::Dict& Value::GetDict() const { … }
Value::Dict& Value::GetDict() { … }
const Value::List& Value::GetList() const { … }
Value::List& Value::GetList() { … }
std::string Value::TakeString() && { … }
Value::Dict Value::TakeDict() && { … }
Value::List Value::TakeList() && { … }
Value::Dict::Dict() = default;
Value::Dict::Dict(Dict&&) noexcept = default;
Value::Dict& Value::Dict::operator=(Dict&&) noexcept = default;
Value::Dict::~Dict() = default;
bool Value::Dict::empty() const { … }
size_t Value::Dict::size() const { … }
Value::Dict::iterator Value::Dict::begin() { … }
Value::Dict::const_iterator Value::Dict::begin() const { … }
Value::Dict::const_iterator Value::Dict::cbegin() const { … }
Value::Dict::iterator Value::Dict::end() { … }
Value::Dict::const_iterator Value::Dict::end() const { … }
Value::Dict::const_iterator Value::Dict::cend() const { … }
bool Value::Dict::contains(std::string_view key) const { … }
void Value::Dict::clear() { … }
Value::Dict::iterator Value::Dict::erase(iterator pos) { … }
Value::Dict::iterator Value::Dict::erase(const_iterator pos) { … }
Value::Dict Value::Dict::Clone() const { … }
void Value::Dict::Merge(Dict dict) { … }
const Value* Value::Dict::Find(std::string_view key) const { … }
Value* Value::Dict::Find(std::string_view key) { … }
std::optional<bool> Value::Dict::FindBool(std::string_view key) const { … }
std::optional<int> Value::Dict::FindInt(std::string_view key) const { … }
std::optional<double> Value::Dict::FindDouble(std::string_view key) const { … }
const std::string* Value::Dict::FindString(std::string_view key) const { … }
std::string* Value::Dict::FindString(std::string_view key) { … }
const Value::BlobStorage* Value::Dict::FindBlob(std::string_view key) const { … }
const Value::Dict* Value::Dict::FindDict(std::string_view key) const { … }
Value::Dict* Value::Dict::FindDict(std::string_view key) { … }
const Value::List* Value::Dict::FindList(std::string_view key) const { … }
Value::List* Value::Dict::FindList(std::string_view key) { … }
Value::Dict* Value::Dict::EnsureDict(std::string_view key) { … }
Value::List* Value::Dict::EnsureList(std::string_view key) { … }
Value* Value::Dict::Set(std::string_view key, Value&& value) & { … }
Value* Value::Dict::Set(std::string_view key, bool value) & { … }
Value* Value::Dict::Set(std::string_view key, int value) & { … }
Value* Value::Dict::Set(std::string_view key, double value) & { … }
Value* Value::Dict::Set(std::string_view key, std::string_view value) & { … }
Value* Value::Dict::Set(std::string_view key, std::u16string_view value) & { … }
Value* Value::Dict::Set(std::string_view key, const char* value) & { … }
Value* Value::Dict::Set(std::string_view key, const char16_t* value) & { … }
Value* Value::Dict::Set(std::string_view key, std::string&& value) & { … }
Value* Value::Dict::Set(std::string_view key, BlobStorage&& value) & { … }
Value* Value::Dict::Set(std::string_view key, Dict&& value) & { … }
Value* Value::Dict::Set(std::string_view key, List&& value) & { … }
Value::Dict&& Value::Dict::Set(std::string_view key, Value&& value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, bool value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, int value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, double value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key,
std::string_view value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key,
std::u16string_view value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, const char* value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, const char16_t* value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, std::string&& value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, BlobStorage&& value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, Dict&& value) && { … }
Value::Dict&& Value::Dict::Set(std::string_view key, List&& value) && { … }
bool Value::Dict::Remove(std::string_view key) { … }
std::optional<Value> Value::Dict::Extract(std::string_view key) { … }
const Value* Value::Dict::FindByDottedPath(std::string_view path) const { … }
Value* Value::Dict::FindByDottedPath(std::string_view path) { … }
std::optional<bool> Value::Dict::FindBoolByDottedPath(
std::string_view path) const { … }
std::optional<int> Value::Dict::FindIntByDottedPath(
std::string_view path) const { … }
std::optional<double> Value::Dict::FindDoubleByDottedPath(
std::string_view path) const { … }
const std::string* Value::Dict::FindStringByDottedPath(
std::string_view path) const { … }
std::string* Value::Dict::FindStringByDottedPath(std::string_view path) { … }
const Value::BlobStorage* Value::Dict::FindBlobByDottedPath(
std::string_view path) const { … }
const Value::Dict* Value::Dict::FindDictByDottedPath(
std::string_view path) const { … }
Value::Dict* Value::Dict::FindDictByDottedPath(std::string_view path) { … }
const Value::List* Value::Dict::FindListByDottedPath(
std::string_view path) const { … }
Value::List* Value::Dict::FindListByDottedPath(std::string_view path) { … }
Value* Value::Dict::SetByDottedPath(std::string_view path, Value&& value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path, bool value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path, int value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path, double value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path,
std::string_view value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path,
std::u16string_view value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path,
const char* value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path,
const char16_t* value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path,
std::string&& value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path,
BlobStorage&& value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path, Dict&& value) & { … }
Value* Value::Dict::SetByDottedPath(std::string_view path, List&& value) & { … }
bool Value::Dict::RemoveByDottedPath(std::string_view path) { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
Value&& value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
bool value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
int value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
double value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
std::string_view value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
std::u16string_view value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
const char* value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
const char16_t* value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
std::string&& value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
BlobStorage&& value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
Dict&& value) && { … }
Value::Dict&& Value::Dict::SetByDottedPath(std::string_view path,
List&& value) && { … }
std::optional<Value> Value::Dict::ExtractByDottedPath(std::string_view path) { … }
size_t Value::Dict::EstimateMemoryUsage() const { … }
std::string Value::Dict::DebugString() const { … }
#if BUILDFLAG(ENABLE_BASE_TRACING)
void Value::Dict::WriteIntoTrace(perfetto::TracedValue context) const { … }
#endif
Value::Dict::Dict(
const flat_map<std::string, std::unique_ptr<Value>>& storage) { … }
bool operator==(const Value::Dict& lhs, const Value::Dict& rhs) { … }
bool operator!=(const Value::Dict& lhs, const Value::Dict& rhs) { … }
bool operator<(const Value::Dict& lhs, const Value::Dict& rhs) { … }
bool operator>(const Value::Dict& lhs, const Value::Dict& rhs) { … }
bool operator<=(const Value::Dict& lhs, const Value::Dict& rhs) { … }
bool operator>=(const Value::Dict& lhs, const Value::Dict& rhs) { … }
Value::List Value::List::with_capacity(size_t capacity) { … }
Value::List::List() = default;
Value::List::List(List&&) noexcept = default;
Value::List& Value::List::operator=(List&&) noexcept = default;
Value::List::~List() = default;
bool Value::List::empty() const { … }
size_t Value::List::size() const { … }
Value::List::iterator Value::List::begin() { … }
Value::List::const_iterator Value::List::begin() const { … }
Value::List::const_iterator Value::List::cbegin() const { … }
Value::List::iterator Value::List::end() { … }
Value::List::const_iterator Value::List::end() const { … }
Value::List::const_iterator Value::List::cend() const { … }
Value::List::reverse_iterator Value::List::rend() { … }
Value::List::const_reverse_iterator Value::List::rend() const { … }
Value::List::reverse_iterator Value::List::rbegin() { … }
Value::List::const_reverse_iterator Value::List::rbegin() const { … }
const Value& Value::List::front() const { … }
Value& Value::List::front() { … }
const Value& Value::List::back() const { … }
Value& Value::List::back() { … }
void Value::List::reserve(size_t capacity) { … }
void Value::List::resize(size_t new_size) { … }
const Value& Value::List::operator[](size_t index) const { … }
Value& Value::List::operator[](size_t index) { … }
void Value::List::clear() { … }
Value::List::iterator Value::List::erase(iterator pos) { … }
Value::List::const_iterator Value::List::erase(const_iterator pos) { … }
Value::List::iterator Value::List::erase(iterator first, iterator last) { … }
Value::List::const_iterator Value::List::erase(const_iterator first,
const_iterator last) { … }
Value::List Value::List::Clone() const { … }
void Value::List::Append(Value&& value) & { … }
void Value::List::Append(bool value) & { … }
void Value::List::Append(int value) & { … }
void Value::List::Append(double value) & { … }
void Value::List::Append(std::string_view value) & { … }
void Value::List::Append(std::u16string_view value) & { … }
void Value::List::Append(const char* value) & { … }
void Value::List::Append(const char16_t* value) & { … }
void Value::List::Append(std::string&& value) & { … }
void Value::List::Append(BlobStorage&& value) & { … }
void Value::List::Append(Dict&& value) & { … }
void Value::List::Append(List&& value) & { … }
Value::List&& Value::List::Append(Value&& value) && { … }
Value::List&& Value::List::Append(bool value) && { … }
Value::List&& Value::List::Append(int value) && { … }
Value::List&& Value::List::Append(double value) && { … }
Value::List&& Value::List::Append(std::string_view value) && { … }
Value::List&& Value::List::Append(std::u16string_view value) && { … }
Value::List&& Value::List::Append(const char* value) && { … }
Value::List&& Value::List::Append(const char16_t* value) && { … }
Value::List&& Value::List::Append(std::string&& value) && { … }
Value::List&& Value::List::Append(BlobStorage&& value) && { … }
Value::List&& Value::List::Append(Dict&& value) && { … }
Value::List&& Value::List::Append(List&& value) && { … }
Value::List::iterator Value::List::Insert(const_iterator pos, Value&& value) { … }
size_t Value::List::EraseValue(const Value& value) { … }
size_t Value::List::EstimateMemoryUsage() const { … }
std::string Value::List::DebugString() const { … }
#if BUILDFLAG(ENABLE_BASE_TRACING)
void Value::List::WriteIntoTrace(perfetto::TracedValue context) const { … }
#endif
Value::List::List(const std::vector<Value>& storage) { … }
bool operator==(const Value::List& lhs, const Value::List& rhs) { … }
bool operator!=(const Value::List& lhs, const Value::List& rhs) { … }
bool operator<(const Value::List& lhs, const Value::List& rhs) { … }
bool operator>(const Value::List& lhs, const Value::List& rhs) { … }
bool operator<=(const Value::List& lhs, const Value::List& rhs) { … }
bool operator>=(const Value::List& lhs, const Value::List& rhs) { … }
bool operator==(const Value& lhs, const Value& rhs) { … }
bool operator!=(const Value& lhs, const Value& rhs) { … }
bool operator<(const Value& lhs, const Value& rhs) { … }
bool operator>(const Value& lhs, const Value& rhs) { … }
bool operator<=(const Value& lhs, const Value& rhs) { … }
bool operator>=(const Value& lhs, const Value& rhs) { … }
bool operator==(const Value& lhs, bool rhs) { … }
bool operator==(const Value& lhs, int rhs) { … }
bool operator==(const Value& lhs, double rhs) { … }
bool operator==(const Value& lhs, std::string_view rhs) { … }
bool operator==(const Value& lhs, const Value::Dict& rhs) { … }
bool operator==(const Value& lhs, const Value::List& rhs) { … }
size_t Value::EstimateMemoryUsage() const { … }
std::string Value::DebugString() const { … }
#if BUILDFLAG(ENABLE_BASE_TRACING)
void Value::WriteIntoTrace(perfetto::TracedValue context) const { … }
#endif
ValueView::ValueView(const Value& value)
: … { … }
Value ValueView::ToValue() const { … }
ValueSerializer::~ValueSerializer() = default;
ValueDeserializer::~ValueDeserializer() = default;
std::ostream& operator<<(std::ostream& out, const Value& value) { … }
std::ostream& operator<<(std::ostream& out, const Value::Dict& dict) { … }
std::ostream& operator<<(std::ostream& out, const Value::List& list) { … }
std::ostream& operator<<(std::ostream& out, const Value::Type& type) { … }
}