xref: /aosp_15_r20/external/cronet/base/trace_event/traced_value.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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