1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TRACE_EVENT_TRACED_VALUE_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_TRACE_EVENT_TRACED_VALUE_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <memory> 11*6777b538SAndroid Build Coastguard Worker #include <sstream> 12*6777b538SAndroid Build Coastguard Worker #include <string> 13*6777b538SAndroid Build Coastguard Worker #include <string_view> 14*6777b538SAndroid Build Coastguard Worker #include <vector> 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_arguments.h" 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker namespace base { 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker class Value; 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker namespace trace_event { 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker class TraceEventMemoryOverhead; 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT TracedValue : public ConvertableToTraceFormat { 30*6777b538SAndroid Build Coastguard Worker public: 31*6777b538SAndroid Build Coastguard Worker // TODO(oysteine): |capacity| is not used in any production code. Consider 32*6777b538SAndroid Build Coastguard Worker // removing it. 33*6777b538SAndroid Build Coastguard Worker explicit TracedValue(size_t capacity = 0); 34*6777b538SAndroid Build Coastguard Worker TracedValue(const TracedValue&) = delete; 35*6777b538SAndroid Build Coastguard Worker TracedValue& operator=(const TracedValue&) = delete; 36*6777b538SAndroid Build Coastguard Worker ~TracedValue() override; 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker void EndDictionary(); 39*6777b538SAndroid Build Coastguard Worker void EndArray(); 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker // These methods assume that |name| is a long lived "quoted" string. 42*6777b538SAndroid Build Coastguard Worker void SetInteger(const char* name, int value); 43*6777b538SAndroid Build Coastguard Worker void SetDouble(const char* name, double value); 44*6777b538SAndroid Build Coastguard Worker void SetBoolean(const char* name, bool value); 45*6777b538SAndroid Build Coastguard Worker void SetString(const char* name, std::string_view value); 46*6777b538SAndroid Build Coastguard Worker void SetValue(const char* name, TracedValue* value); 47*6777b538SAndroid Build Coastguard Worker void SetPointer(const char* name, const void* value); 48*6777b538SAndroid Build Coastguard Worker void BeginDictionary(const char* name); 49*6777b538SAndroid Build Coastguard Worker void BeginArray(const char* name); 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker // These, instead, can be safely passed a temporary string. 52*6777b538SAndroid Build Coastguard Worker void SetIntegerWithCopiedName(std::string_view name, int value); 53*6777b538SAndroid Build Coastguard Worker void SetDoubleWithCopiedName(std::string_view name, double value); 54*6777b538SAndroid Build Coastguard Worker void SetBooleanWithCopiedName(std::string_view name, bool value); 55*6777b538SAndroid Build Coastguard Worker void SetStringWithCopiedName(std::string_view name, std::string_view value); 56*6777b538SAndroid Build Coastguard Worker void SetValueWithCopiedName(std::string_view name, TracedValue* value); 57*6777b538SAndroid Build Coastguard Worker void SetPointerWithCopiedName(std::string_view name, const void* value); 58*6777b538SAndroid Build Coastguard Worker void BeginDictionaryWithCopiedName(std::string_view name); 59*6777b538SAndroid Build Coastguard Worker void BeginArrayWithCopiedName(std::string_view name); 60*6777b538SAndroid Build Coastguard Worker 61*6777b538SAndroid Build Coastguard Worker void AppendInteger(int); 62*6777b538SAndroid Build Coastguard Worker void AppendDouble(double); 63*6777b538SAndroid Build Coastguard Worker void AppendBoolean(bool); 64*6777b538SAndroid Build Coastguard Worker void AppendString(std::string_view); 65*6777b538SAndroid Build Coastguard Worker void AppendPointer(const void*); 66*6777b538SAndroid Build Coastguard Worker void BeginArray(); 67*6777b538SAndroid Build Coastguard Worker void BeginDictionary(); 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker // ConvertableToTraceFormat implementation. 70*6777b538SAndroid Build Coastguard Worker void AppendAsTraceFormat(std::string* out) const override; 71*6777b538SAndroid Build Coastguard Worker bool AppendToProto(ProtoAppender* appender) const override; 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override; 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker // Helper to auto-close an array. The call to |ArrayScope::~ArrayScope| closes 76*6777b538SAndroid Build Coastguard Worker // the array. 77*6777b538SAndroid Build Coastguard Worker // 78*6777b538SAndroid Build Coastguard Worker // To be constructed using: 79*6777b538SAndroid Build Coastguard Worker // |TracedValue::AppendArrayScoped| 80*6777b538SAndroid Build Coastguard Worker // |TracedValue::BeginArrayScoped| 81*6777b538SAndroid Build Coastguard Worker // |TracedValue::BeginArrayScopedWithCopiedName| 82*6777b538SAndroid Build Coastguard Worker // 83*6777b538SAndroid Build Coastguard Worker // |ArrayScope| holds a |TracedValue| pointer which should remain a valid 84*6777b538SAndroid Build Coastguard Worker // pointer until |ArrayScope::~ArrayScope| is called. 85*6777b538SAndroid Build Coastguard Worker // 86*6777b538SAndroid Build Coastguard Worker // |ArrayScope::~ArrayScope| calls |TracedValue::EndArray| (which checks if 87*6777b538SAndroid Build Coastguard Worker // the held |TracedValue*| is in array state). 88*6777b538SAndroid Build Coastguard Worker // 89*6777b538SAndroid Build Coastguard Worker // Example: 90*6777b538SAndroid Build Coastguard Worker // std::unique_ptr<TracedValue> value(new TracedValue()); 91*6777b538SAndroid Build Coastguard Worker // { 92*6777b538SAndroid Build Coastguard Worker // auto scope = value->BeginArrayScoped("array_name"); 93*6777b538SAndroid Build Coastguard Worker // value->AppendBoolean(false); 94*6777b538SAndroid Build Coastguard Worker // } 95*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ArrayScope { 96*6777b538SAndroid Build Coastguard Worker public: 97*6777b538SAndroid Build Coastguard Worker ArrayScope(const ArrayScope&) = delete; 98*6777b538SAndroid Build Coastguard Worker ArrayScope(ArrayScope&&) = default; 99*6777b538SAndroid Build Coastguard Worker ArrayScope& operator=(const ArrayScope&) = delete; 100*6777b538SAndroid Build Coastguard Worker ArrayScope& operator=(ArrayScope&&) = default; 101*6777b538SAndroid Build Coastguard Worker ~ArrayScope(); 102*6777b538SAndroid Build Coastguard Worker 103*6777b538SAndroid Build Coastguard Worker private: 104*6777b538SAndroid Build Coastguard Worker explicit ArrayScope(TracedValue* value); 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker raw_ptr<TracedValue> value_; 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker friend class TracedValue; 109*6777b538SAndroid Build Coastguard Worker }; 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker // Call |BeginArray| or |BeginArrayWithCopiedName| with no / the same 112*6777b538SAndroid Build Coastguard Worker // parameter and return an |ArrayScope| holding |this|. 113*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ArrayScope AppendArrayScoped(); 114*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ArrayScope BeginArrayScoped(const char* name); 115*6777b538SAndroid Build Coastguard Worker [[nodiscard]] ArrayScope BeginArrayScopedWithCopiedName( 116*6777b538SAndroid Build Coastguard Worker std::string_view name); 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker // Helper to auto-close a dictionary. The call to 119*6777b538SAndroid Build Coastguard Worker // |DictionaryScope::~DictionaryScope| closes the dictionary. 120*6777b538SAndroid Build Coastguard Worker // 121*6777b538SAndroid Build Coastguard Worker // To be constructed using: 122*6777b538SAndroid Build Coastguard Worker // |TracedValue::AppendDictionaryScoped| 123*6777b538SAndroid Build Coastguard Worker // |TracedValue::BeginDictionaryScoped| 124*6777b538SAndroid Build Coastguard Worker // |TracedValue::BeginDictionaryScopedWithCopiedName| 125*6777b538SAndroid Build Coastguard Worker // 126*6777b538SAndroid Build Coastguard Worker // |DictionaryScope| holds a |TracedValue| pointer which should remain a valid 127*6777b538SAndroid Build Coastguard Worker // pointer until |DictionaryScope::~DictionaryScope| is called. 128*6777b538SAndroid Build Coastguard Worker // 129*6777b538SAndroid Build Coastguard Worker // |DictionaryScope::~DictionaryScope| calls |TracedValue::EndDictionary| 130*6777b538SAndroid Build Coastguard Worker // (which checks if the held |TracedValue*| is in dictionary state). 131*6777b538SAndroid Build Coastguard Worker // 132*6777b538SAndroid Build Coastguard Worker // Example: 133*6777b538SAndroid Build Coastguard Worker // std::unique_ptr<TracedValue> value(new TracedValue()); 134*6777b538SAndroid Build Coastguard Worker // { 135*6777b538SAndroid Build Coastguard Worker // auto scope = value->BeginDictionaryScoped("dictionary_name"); 136*6777b538SAndroid Build Coastguard Worker // value->SetBoolean("my_boolean", false); 137*6777b538SAndroid Build Coastguard Worker // } 138*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DictionaryScope { 139*6777b538SAndroid Build Coastguard Worker public: 140*6777b538SAndroid Build Coastguard Worker DictionaryScope(const DictionaryScope&) = delete; 141*6777b538SAndroid Build Coastguard Worker DictionaryScope(DictionaryScope&&) = default; 142*6777b538SAndroid Build Coastguard Worker DictionaryScope& operator=(const DictionaryScope&) = delete; 143*6777b538SAndroid Build Coastguard Worker DictionaryScope& operator=(DictionaryScope&&) = default; 144*6777b538SAndroid Build Coastguard Worker ~DictionaryScope(); 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker private: 147*6777b538SAndroid Build Coastguard Worker explicit DictionaryScope(TracedValue* value); 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker raw_ptr<TracedValue> value_; 150*6777b538SAndroid Build Coastguard Worker 151*6777b538SAndroid Build Coastguard Worker friend class TracedValue; 152*6777b538SAndroid Build Coastguard Worker }; 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker // Call |BeginDictionary| or |BeginDictionaryWithCopiedName| with no / the 155*6777b538SAndroid Build Coastguard Worker // same parameter and return a |DictionaryScope| holding |this|. 156*6777b538SAndroid Build Coastguard Worker [[nodiscard]] DictionaryScope AppendDictionaryScoped(); 157*6777b538SAndroid Build Coastguard Worker [[nodiscard]] DictionaryScope BeginDictionaryScoped(const char* name); 158*6777b538SAndroid Build Coastguard Worker [[nodiscard]] DictionaryScope BeginDictionaryScopedWithCopiedName( 159*6777b538SAndroid Build Coastguard Worker std::string_view name); 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Array; 162*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Dictionary; 163*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ValueHolder; 164*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ArrayItem; 165*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DictionaryItem; 166*6777b538SAndroid Build Coastguard Worker 167*6777b538SAndroid Build Coastguard Worker // Helper to enable easier initialization of |TracedValue|. This is intended 168*6777b538SAndroid Build Coastguard Worker // for quick local debugging as there is overhead of creating 169*6777b538SAndroid Build Coastguard Worker // |std::initializer_list| of name-value objects (in the case of containers 170*6777b538SAndroid Build Coastguard Worker // the value is also a |std::initializer_list|). Generally the helper types 171*6777b538SAndroid Build Coastguard Worker // |TracedValue::Dictionary|, |TracedValue::Array|, 172*6777b538SAndroid Build Coastguard Worker // |TracedValue::DictionaryItem|, |TracedValue::ArrayItem| must be valid as 173*6777b538SAndroid Build Coastguard Worker // well as their internals (e.g., |std::string_view| data should be valid 174*6777b538SAndroid Build Coastguard Worker // when |TracedValue::Build| is called; |TracedValue::Array| or 175*6777b538SAndroid Build Coastguard Worker // |TracedValue::Dictionary| holds a |std::initializer_list| whose underlying 176*6777b538SAndroid Build Coastguard Worker // array needs to be valid when calling |TracedValue::Build|). 177*6777b538SAndroid Build Coastguard Worker // 178*6777b538SAndroid Build Coastguard Worker // Example: 179*6777b538SAndroid Build Coastguard Worker // auto value = TracedValue::Build({ 180*6777b538SAndroid Build Coastguard Worker // {"int_var_name", 42}, 181*6777b538SAndroid Build Coastguard Worker // {"double_var_name", 3.14}, 182*6777b538SAndroid Build Coastguard Worker // {"string_var_name", "hello world"}, 183*6777b538SAndroid Build Coastguard Worker // {"empty_array", TracedValue::Array({})}, 184*6777b538SAndroid Build Coastguard Worker // {"dictionary", TracedValue::Dictionary({ 185*6777b538SAndroid Build Coastguard Worker // {"my_ptr", static_cast<void*>(my_ptr)}, 186*6777b538SAndroid Build Coastguard Worker // {"nested_array", TracedValue::Array({1, false, 0.5})}, 187*6777b538SAndroid Build Coastguard Worker // })}, 188*6777b538SAndroid Build Coastguard Worker // }); 189*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<TracedValue> Build( 190*6777b538SAndroid Build Coastguard Worker const std::initializer_list<DictionaryItem> items); 191*6777b538SAndroid Build Coastguard Worker 192*6777b538SAndroid Build Coastguard Worker // An |Array| instance represents an array of |ArrayItem| objects. This is a 193*6777b538SAndroid Build Coastguard Worker // helper to allow initializer list like construction of arrays using 194*6777b538SAndroid Build Coastguard Worker // |TracedValue::Build|. 195*6777b538SAndroid Build Coastguard Worker // 196*6777b538SAndroid Build Coastguard Worker // An instance holds an |std::initializer_list<TracedValue::ArrayItem>| and is 197*6777b538SAndroid Build Coastguard Worker // cheap to copy (copying the initializer_list does not copy the underlying 198*6777b538SAndroid Build Coastguard Worker // objects). The underlying array must exist at the time when 199*6777b538SAndroid Build Coastguard Worker // |TracedValue::Build| is called. 200*6777b538SAndroid Build Coastguard Worker class Array { 201*6777b538SAndroid Build Coastguard Worker public: 202*6777b538SAndroid Build Coastguard Worker // This constructor expects that the initializer_list is valid when 203*6777b538SAndroid Build Coastguard Worker // |TracedValue::Build| is called. 204*6777b538SAndroid Build Coastguard Worker Array(const std::initializer_list<ArrayItem> items); 205*6777b538SAndroid Build Coastguard Worker Array(Array&&); 206*6777b538SAndroid Build Coastguard Worker void WriteToValue(TracedValue* value) const; 207*6777b538SAndroid Build Coastguard Worker 208*6777b538SAndroid Build Coastguard Worker private: 209*6777b538SAndroid Build Coastguard Worker std::initializer_list<ArrayItem> items_; 210*6777b538SAndroid Build Coastguard Worker }; 211*6777b538SAndroid Build Coastguard Worker 212*6777b538SAndroid Build Coastguard Worker // A helper to hold a dictionary. Similar to |TracedValue::Array|. 213*6777b538SAndroid Build Coastguard Worker class Dictionary { 214*6777b538SAndroid Build Coastguard Worker public: 215*6777b538SAndroid Build Coastguard Worker // This constructor expects that the initializer_list is valid when 216*6777b538SAndroid Build Coastguard Worker // |TracedValue::Build| is called. 217*6777b538SAndroid Build Coastguard Worker Dictionary(const std::initializer_list<DictionaryItem> items); 218*6777b538SAndroid Build Coastguard Worker Dictionary(Dictionary&&); 219*6777b538SAndroid Build Coastguard Worker void WriteToValue(TracedValue* value) const; 220*6777b538SAndroid Build Coastguard Worker 221*6777b538SAndroid Build Coastguard Worker private: 222*6777b538SAndroid Build Coastguard Worker std::initializer_list<DictionaryItem> items_; 223*6777b538SAndroid Build Coastguard Worker }; 224*6777b538SAndroid Build Coastguard Worker 225*6777b538SAndroid Build Coastguard Worker // A |ValueHolder| holds a single value or a container (int, double... or an 226*6777b538SAndroid Build Coastguard Worker // |Array| / |Dictionary|). Not to be used outside of the context of 227*6777b538SAndroid Build Coastguard Worker // |TracedValue::Build| (has one parameter implicit constructors). 228*6777b538SAndroid Build Coastguard Worker // 229*6777b538SAndroid Build Coastguard Worker // Base class for |TracedValue::ArrayItem| and |TracedValue::DictionaryItem|. 230*6777b538SAndroid Build Coastguard Worker class ValueHolder { 231*6777b538SAndroid Build Coastguard Worker public: 232*6777b538SAndroid Build Coastguard Worker // Implicit constructors allow constructing |DictionaryItem| without having 233*6777b538SAndroid Build Coastguard Worker // to write |{"name", TracedValue::ValueHolder(1)}|. 234*6777b538SAndroid Build Coastguard Worker ValueHolder(int value); // NOLINT(google-explicit-constructor) 235*6777b538SAndroid Build Coastguard Worker ValueHolder(double value); // NOLINT(google-explicit-constructor) 236*6777b538SAndroid Build Coastguard Worker ValueHolder(bool value); // NOLINT(google-explicit-constructor) 237*6777b538SAndroid Build Coastguard Worker ValueHolder(void* value); // NOLINT(google-explicit-constructor) 238*6777b538SAndroid Build Coastguard Worker // std::string_view's backing storage / const char* pointer needs to remain 239*6777b538SAndroid Build Coastguard Worker // valid until TracedValue::Build is called. 240*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor) 241*6777b538SAndroid Build Coastguard Worker ValueHolder(std::string_view value); 242*6777b538SAndroid Build Coastguard Worker // Create a copy to avoid holding a reference to a non-existing string: 243*6777b538SAndroid Build Coastguard Worker // 244*6777b538SAndroid Build Coastguard Worker // Example: 245*6777b538SAndroid Build Coastguard Worker // TracedValue::Build({{"my_string", std::string("std::string value")}}); 246*6777b538SAndroid Build Coastguard Worker // Explanation: 247*6777b538SAndroid Build Coastguard Worker // 1. std::string temporary is passed to the constructor of |ValueHolder|. 248*6777b538SAndroid Build Coastguard Worker // 2. |ValueHolder| is passed to the constructor of |DictionaryItem|. 249*6777b538SAndroid Build Coastguard Worker // 3. |Build| iterates initializer_list of |DictionaryItems|. 250*6777b538SAndroid Build Coastguard Worker // 251*6777b538SAndroid Build Coastguard Worker // If the original |ValueHolder| kept just a reference to the string (or 252*6777b538SAndroid Build Coastguard Worker // a |std::string_view|) then |Build| is undefined behaviour, as it is 253*6777b538SAndroid Build Coastguard Worker // passing a reference to an out-of-scope temporary to 254*6777b538SAndroid Build Coastguard Worker // |TracedValue::SetString|. 255*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor) 256*6777b538SAndroid Build Coastguard Worker ValueHolder(std::string value); 257*6777b538SAndroid Build Coastguard Worker // Define an explicit overload for const char* to resolve the ambiguity 258*6777b538SAndroid Build Coastguard Worker // between the std::string_view, void*, and bool constructors for string 259*6777b538SAndroid Build Coastguard Worker // literals. 260*6777b538SAndroid Build Coastguard Worker ValueHolder(const char* value); // NOLINT(google-explicit-constructor) 261*6777b538SAndroid Build Coastguard Worker ValueHolder(Array& value); // NOLINT(google-explicit-constructor) 262*6777b538SAndroid Build Coastguard Worker ValueHolder(Dictionary& value); // NOLINT(google-explicit-constructor) 263*6777b538SAndroid Build Coastguard Worker ValueHolder(ValueHolder&&); 264*6777b538SAndroid Build Coastguard Worker 265*6777b538SAndroid Build Coastguard Worker protected: 266*6777b538SAndroid Build Coastguard Worker void WriteToValue(TracedValue* value) const; 267*6777b538SAndroid Build Coastguard Worker void WriteToValue(const char* name, TracedValue* value) const; 268*6777b538SAndroid Build Coastguard Worker 269*6777b538SAndroid Build Coastguard Worker private: 270*6777b538SAndroid Build Coastguard Worker union KeptValue { 271*6777b538SAndroid Build Coastguard Worker // Copy is handled by the holder (based on 272*6777b538SAndroid Build Coastguard Worker // |TracedValue::ValueHolder::kept_value_type_|). 273*6777b538SAndroid Build Coastguard Worker int int_value; 274*6777b538SAndroid Build Coastguard Worker double double_value; 275*6777b538SAndroid Build Coastguard Worker bool bool_value; 276*6777b538SAndroid Build Coastguard Worker std::string_view string_piece_value; 277*6777b538SAndroid Build Coastguard Worker std::string std_string_value; 278*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter 279*6777b538SAndroid Build Coastguard Worker // for: #union 280*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION void* void_ptr_value; 281*6777b538SAndroid Build Coastguard Worker Array array_value; 282*6777b538SAndroid Build Coastguard Worker Dictionary dictionary_value; 283*6777b538SAndroid Build Coastguard Worker 284*6777b538SAndroid Build Coastguard Worker // Default constructor is implicitly deleted because union field has a 285*6777b538SAndroid Build Coastguard Worker // non-trivial default constructor. KeptValue()286*6777b538SAndroid Build Coastguard Worker KeptValue() {} // NOLINT(modernize-use-equals-default) ~KeptValue()287*6777b538SAndroid Build Coastguard Worker ~KeptValue() {} // NOLINT(modernize-use-equals-default) 288*6777b538SAndroid Build Coastguard Worker }; 289*6777b538SAndroid Build Coastguard Worker 290*6777b538SAndroid Build Coastguard Worker // Reimplementing a subset of C++17 std::variant. 291*6777b538SAndroid Build Coastguard Worker enum class KeptValueType { 292*6777b538SAndroid Build Coastguard Worker kIntType, 293*6777b538SAndroid Build Coastguard Worker kDoubleType, 294*6777b538SAndroid Build Coastguard Worker kBoolType, 295*6777b538SAndroid Build Coastguard Worker kStringPieceType, 296*6777b538SAndroid Build Coastguard Worker kStdStringType, 297*6777b538SAndroid Build Coastguard Worker kVoidPtrType, 298*6777b538SAndroid Build Coastguard Worker kArrayType, 299*6777b538SAndroid Build Coastguard Worker kDictionaryType, 300*6777b538SAndroid Build Coastguard Worker }; 301*6777b538SAndroid Build Coastguard Worker 302*6777b538SAndroid Build Coastguard Worker KeptValue kept_value_; 303*6777b538SAndroid Build Coastguard Worker KeptValueType kept_value_type_; 304*6777b538SAndroid Build Coastguard Worker }; 305*6777b538SAndroid Build Coastguard Worker 306*6777b538SAndroid Build Coastguard Worker // |ArrayItem| is a |ValueHolder| which can be used to construct an |Array|. 307*6777b538SAndroid Build Coastguard Worker class ArrayItem : public ValueHolder { 308*6777b538SAndroid Build Coastguard Worker public: 309*6777b538SAndroid Build Coastguard Worker // Implicit constructors allow calling |TracedValue::Array({1, true, 3.14})| 310*6777b538SAndroid Build Coastguard Worker // instead of |TracedValue::Array({TracedValue::ArrayItem(1), 311*6777b538SAndroid Build Coastguard Worker // TracedValue::ArrayItem(true), TracedValue::ArrayItem(3.14)})|. 312*6777b538SAndroid Build Coastguard Worker template <typename T> 313*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor) ArrayItem(T value)314*6777b538SAndroid Build Coastguard Worker ArrayItem(T value) : ValueHolder(value) {} 315*6777b538SAndroid Build Coastguard Worker 316*6777b538SAndroid Build Coastguard Worker void WriteToValue(TracedValue* value) const; 317*6777b538SAndroid Build Coastguard Worker }; 318*6777b538SAndroid Build Coastguard Worker 319*6777b538SAndroid Build Coastguard Worker // |DictionaryItem| instance represents a single name-value pair. 320*6777b538SAndroid Build Coastguard Worker // 321*6777b538SAndroid Build Coastguard Worker // |name| is assumed to be a long lived "quoted" string. 322*6777b538SAndroid Build Coastguard Worker class DictionaryItem : public ValueHolder { 323*6777b538SAndroid Build Coastguard Worker public: 324*6777b538SAndroid Build Coastguard Worker // These constructors assume that |name| is a long lived "quoted" string. 325*6777b538SAndroid Build Coastguard Worker template <typename T> DictionaryItem(const char * name,T value)326*6777b538SAndroid Build Coastguard Worker DictionaryItem(const char* name, T value) 327*6777b538SAndroid Build Coastguard Worker : ValueHolder(value), name_(name) {} 328*6777b538SAndroid Build Coastguard Worker 329*6777b538SAndroid Build Coastguard Worker void WriteToValue(TracedValue* value) const; 330*6777b538SAndroid Build Coastguard Worker 331*6777b538SAndroid Build Coastguard Worker private: 332*6777b538SAndroid Build Coastguard Worker const char* name_; 333*6777b538SAndroid Build Coastguard Worker }; 334*6777b538SAndroid Build Coastguard Worker 335*6777b538SAndroid Build Coastguard Worker // A custom serialization class can be supplied by implementing the 336*6777b538SAndroid Build Coastguard Worker // Writer interface and supplying a factory class to SetWriterFactoryCallback. 337*6777b538SAndroid Build Coastguard Worker // Primarily used by Perfetto to write TracedValues directly into its proto 338*6777b538SAndroid Build Coastguard Worker // format, which lets us do a direct memcpy() in AppendToProto() rather than 339*6777b538SAndroid Build Coastguard Worker // a JSON serialization step in AppendAsTraceFormat. 340*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Writer { 341*6777b538SAndroid Build Coastguard Worker public: 342*6777b538SAndroid Build Coastguard Worker virtual ~Writer() = default; 343*6777b538SAndroid Build Coastguard Worker 344*6777b538SAndroid Build Coastguard Worker virtual void BeginArray() = 0; 345*6777b538SAndroid Build Coastguard Worker virtual void BeginDictionary() = 0; 346*6777b538SAndroid Build Coastguard Worker virtual void EndDictionary() = 0; 347*6777b538SAndroid Build Coastguard Worker virtual void EndArray() = 0; 348*6777b538SAndroid Build Coastguard Worker 349*6777b538SAndroid Build Coastguard Worker // These methods assume that |name| is a long lived "quoted" string. 350*6777b538SAndroid Build Coastguard Worker virtual void SetInteger(const char* name, int value) = 0; 351*6777b538SAndroid Build Coastguard Worker virtual void SetDouble(const char* name, double value) = 0; 352*6777b538SAndroid Build Coastguard Worker virtual void SetBoolean(const char* name, bool value) = 0; 353*6777b538SAndroid Build Coastguard Worker virtual void SetString(const char* name, std::string_view value) = 0; 354*6777b538SAndroid Build Coastguard Worker virtual void SetValue(const char* name, Writer* value) = 0; 355*6777b538SAndroid Build Coastguard Worker virtual void BeginDictionary(const char* name) = 0; 356*6777b538SAndroid Build Coastguard Worker virtual void BeginArray(const char* name) = 0; 357*6777b538SAndroid Build Coastguard Worker 358*6777b538SAndroid Build Coastguard Worker // These, instead, can be safely passed a temporary string. 359*6777b538SAndroid Build Coastguard Worker virtual void SetIntegerWithCopiedName(std::string_view name, int value) = 0; 360*6777b538SAndroid Build Coastguard Worker virtual void SetDoubleWithCopiedName(std::string_view name, 361*6777b538SAndroid Build Coastguard Worker double value) = 0; 362*6777b538SAndroid Build Coastguard Worker virtual void SetBooleanWithCopiedName(std::string_view name, 363*6777b538SAndroid Build Coastguard Worker bool value) = 0; 364*6777b538SAndroid Build Coastguard Worker virtual void SetStringWithCopiedName(std::string_view name, 365*6777b538SAndroid Build Coastguard Worker std::string_view value) = 0; 366*6777b538SAndroid Build Coastguard Worker virtual void SetValueWithCopiedName(std::string_view name, 367*6777b538SAndroid Build Coastguard Worker Writer* value) = 0; 368*6777b538SAndroid Build Coastguard Worker virtual void BeginDictionaryWithCopiedName(std::string_view name) = 0; 369*6777b538SAndroid Build Coastguard Worker virtual void BeginArrayWithCopiedName(std::string_view name) = 0; 370*6777b538SAndroid Build Coastguard Worker 371*6777b538SAndroid Build Coastguard Worker virtual void AppendInteger(int) = 0; 372*6777b538SAndroid Build Coastguard Worker virtual void AppendDouble(double) = 0; 373*6777b538SAndroid Build Coastguard Worker virtual void AppendBoolean(bool) = 0; 374*6777b538SAndroid Build Coastguard Worker virtual void AppendString(std::string_view) = 0; 375*6777b538SAndroid Build Coastguard Worker 376*6777b538SAndroid Build Coastguard Worker virtual void AppendAsTraceFormat(std::string* out) const = 0; 377*6777b538SAndroid Build Coastguard Worker 378*6777b538SAndroid Build Coastguard Worker virtual bool AppendToProto(ProtoAppender* appender); 379*6777b538SAndroid Build Coastguard Worker 380*6777b538SAndroid Build Coastguard Worker virtual void EstimateTraceMemoryOverhead( 381*6777b538SAndroid Build Coastguard Worker TraceEventMemoryOverhead* overhead) = 0; 382*6777b538SAndroid Build Coastguard Worker 383*6777b538SAndroid Build Coastguard Worker virtual bool IsPickleWriter() const = 0; 384*6777b538SAndroid Build Coastguard Worker virtual bool IsProtoWriter() const = 0; 385*6777b538SAndroid Build Coastguard Worker }; 386*6777b538SAndroid Build Coastguard Worker 387*6777b538SAndroid Build Coastguard Worker typedef std::unique_ptr<Writer> (*WriterFactoryCallback)(size_t capacity); 388*6777b538SAndroid Build Coastguard Worker static void SetWriterFactoryCallback(WriterFactoryCallback callback); 389*6777b538SAndroid Build Coastguard Worker 390*6777b538SAndroid Build Coastguard Worker protected: 391*6777b538SAndroid Build Coastguard Worker TracedValue(size_t capacity, bool forced_json); 392*6777b538SAndroid Build Coastguard Worker 393*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::Value> ToBaseValue() const; 394*6777b538SAndroid Build Coastguard Worker 395*6777b538SAndroid Build Coastguard Worker private: 396*6777b538SAndroid Build Coastguard Worker mutable std::unique_ptr<Writer> writer_; 397*6777b538SAndroid Build Coastguard Worker 398*6777b538SAndroid Build Coastguard Worker #ifndef NDEBUG 399*6777b538SAndroid Build Coastguard Worker // In debug builds checks the pairings of {Start,End}{Dictionary,Array} 400*6777b538SAndroid Build Coastguard Worker std::vector<bool> nesting_stack_; 401*6777b538SAndroid Build Coastguard Worker #endif 402*6777b538SAndroid Build Coastguard Worker }; 403*6777b538SAndroid Build Coastguard Worker 404*6777b538SAndroid Build Coastguard Worker // TracedValue that is convertable to JSON format. This has lower performance 405*6777b538SAndroid Build Coastguard Worker // than the default TracedValue in production code, and should be used only for 406*6777b538SAndroid Build Coastguard Worker // testing and debugging. Should be avoided in tracing. It's for 407*6777b538SAndroid Build Coastguard Worker // testing/debugging code calling value dumping function designed for tracing, 408*6777b538SAndroid Build Coastguard Worker // like the following: 409*6777b538SAndroid Build Coastguard Worker // 410*6777b538SAndroid Build Coastguard Worker // TracedValueJSON value; 411*6777b538SAndroid Build Coastguard Worker // AsValueInto(&value); // which is designed for tracing. 412*6777b538SAndroid Build Coastguard Worker // return value.ToJSON(); 413*6777b538SAndroid Build Coastguard Worker // 414*6777b538SAndroid Build Coastguard Worker // If the code is merely for testing/debugging, base::Value should be used 415*6777b538SAndroid Build Coastguard Worker // instead. 416*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT TracedValueJSON : public TracedValue { 417*6777b538SAndroid Build Coastguard Worker public: 418*6777b538SAndroid Build Coastguard Worker explicit TracedValueJSON(size_t capacity = 0) TracedValue(capacity,true)419*6777b538SAndroid Build Coastguard Worker : TracedValue(capacity, /*forced_josn*/ true) {} 420*6777b538SAndroid Build Coastguard Worker 421*6777b538SAndroid Build Coastguard Worker using TracedValue::ToBaseValue; 422*6777b538SAndroid Build Coastguard Worker 423*6777b538SAndroid Build Coastguard Worker // Converts the value into a JSON string without formatting. Suitable for 424*6777b538SAndroid Build Coastguard Worker // printing a simple value or printing a value in a single line context. 425*6777b538SAndroid Build Coastguard Worker std::string ToJSON() const; 426*6777b538SAndroid Build Coastguard Worker 427*6777b538SAndroid Build Coastguard Worker // Converts the value into a formatted JSON string, with indentation, spaces 428*6777b538SAndroid Build Coastguard Worker // and new lines for better human readability of complex values. 429*6777b538SAndroid Build Coastguard Worker std::string ToFormattedJSON() const; 430*6777b538SAndroid Build Coastguard Worker }; 431*6777b538SAndroid Build Coastguard Worker 432*6777b538SAndroid Build Coastguard Worker } // namespace trace_event 433*6777b538SAndroid Build Coastguard Worker } // namespace base 434*6777b538SAndroid Build Coastguard Worker 435*6777b538SAndroid Build Coastguard Worker #endif // BASE_TRACE_EVENT_TRACED_VALUE_H_ 436