• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pt_types.h"
17 
18 namespace panda::ecmascript::tooling {
19 using ObjectType = RemoteObject::TypeName;
20 using ObjectSubType = RemoteObject::SubTypeName;
21 using ObjectClassName = RemoteObject::ClassName;
22 
23 const std::string ObjectType::Object = "object";        // NOLINT (readability-identifier-naming)
24 const std::string ObjectType::Function = "function";    // NOLINT (readability-identifier-naming)
25 const std::string ObjectType::Undefined = "undefined";  // NOLINT (readability-identifier-naming)
26 const std::string ObjectType::String = "string";        // NOLINT (readability-identifier-naming)
27 const std::string ObjectType::Number = "number";        // NOLINT (readability-identifier-naming)
28 const std::string ObjectType::Boolean = "boolean";      // NOLINT (readability-identifier-naming)
29 const std::string ObjectType::Symbol = "symbol";        // NOLINT (readability-identifier-naming)
30 const std::string ObjectType::Bigint = "bigint";        // NOLINT (readability-identifier-naming)
31 const std::string ObjectType::Wasm = "wasm";            // NOLINT (readability-identifier-naming)
32 
33 const std::string ObjectSubType::Array = "array";              // NOLINT (readability-identifier-naming)
34 const std::string ObjectSubType::Null = "null";                // NOLINT (readability-identifier-naming)
35 const std::string ObjectSubType::Node = "node";                // NOLINT (readability-identifier-naming)
36 const std::string ObjectSubType::Regexp = "regexp";            // NOLINT (readability-identifier-naming)
37 const std::string ObjectSubType::Date = "date";                // NOLINT (readability-identifier-naming)
38 const std::string ObjectSubType::Map = "map";                  // NOLINT (readability-identifier-naming)
39 const std::string ObjectSubType::Set = "set";                  // NOLINT (readability-identifier-naming)
40 const std::string ObjectSubType::Weakmap = "weakmap";          // NOLINT (readability-identifier-naming)
41 const std::string ObjectSubType::Weakset = "weakset";          // NOLINT (readability-identifier-naming)
42 const std::string ObjectSubType::Iterator = "iterator";        // NOLINT (readability-identifier-naming)
43 const std::string ObjectSubType::Generator = "generator";      // NOLINT (readability-identifier-naming)
44 const std::string ObjectSubType::Error = "error";              // NOLINT (readability-identifier-naming)
45 const std::string ObjectSubType::Proxy = "proxy";              // NOLINT (readability-identifier-naming)
46 const std::string ObjectSubType::Promise = "promise";          // NOLINT (readability-identifier-naming)
47 const std::string ObjectSubType::Typedarray = "typedarray";    // NOLINT (readability-identifier-naming)
48 const std::string ObjectSubType::Arraybuffer = "arraybuffer";  // NOLINT (readability-identifier-naming)
49 const std::string ObjectSubType::Dataview = "dataview";        // NOLINT (readability-identifier-naming)
50 const std::string ObjectSubType::I32 = "i32";                  // NOLINT (readability-identifier-naming)
51 const std::string ObjectSubType::I64 = "i64";                  // NOLINT (readability-identifier-naming)
52 const std::string ObjectSubType::F32 = "f32";                  // NOLINT (readability-identifier-naming)
53 const std::string ObjectSubType::F64 = "f64";                  // NOLINT (readability-identifier-naming)
54 const std::string ObjectSubType::V128 = "v128";                // NOLINT (readability-identifier-naming)
55 const std::string ObjectSubType::Externref = "externref";      // NOLINT (readability-identifier-naming)
56 
57 const std::string ObjectClassName::Object = "Object";                  // NOLINT (readability-identifier-naming)
58 const std::string ObjectClassName::Function = "Function";              // NOLINT (readability-identifier-naming)
59 const std::string ObjectClassName::Array = "Array";                    // NOLINT (readability-identifier-naming)
60 const std::string ObjectClassName::Regexp = "RegExp";                  // NOLINT (readability-identifier-naming)
61 const std::string ObjectClassName::Date = "Date";                      // NOLINT (readability-identifier-naming)
62 const std::string ObjectClassName::Map = "Map";                        // NOLINT (readability-identifier-naming)
63 const std::string ObjectClassName::Set = "Set";                        // NOLINT (readability-identifier-naming)
64 const std::string ObjectClassName::Weakmap = "Weakmap";                // NOLINT (readability-identifier-naming)
65 const std::string ObjectClassName::Weakset = "Weakset";                // NOLINT (readability-identifier-naming)
66 const std::string ObjectClassName::Dataview = "Dataview";                // NOLINT (readability-identifier-naming)
67 const std::string ObjectClassName::ArrayIterator = "ArrayIterator";    // NOLINT (readability-identifier-naming)
68 const std::string ObjectClassName::StringIterator = "StringIterator";  // NOLINT (readability-identifier-naming)
69 const std::string ObjectClassName::SetIterator = "SetIterator";        // NOLINT (readability-identifier-naming)
70 const std::string ObjectClassName::MapIterator = "MapIterator";        // NOLINT (readability-identifier-naming)
71 const std::string ObjectClassName::Iterator = "Iterator";              // NOLINT (readability-identifier-naming)
72 const std::string ObjectClassName::Error = "Error";                    // NOLINT (readability-identifier-naming)
73 const std::string ObjectClassName::Proxy = "Object";                   // NOLINT (readability-identifier-naming)
74 const std::string ObjectClassName::Promise = "Promise";                // NOLINT (readability-identifier-naming)
75 const std::string ObjectClassName::Typedarray = "Typedarray";          // NOLINT (readability-identifier-naming)
76 const std::string ObjectClassName::Arraybuffer = "Arraybuffer";        // NOLINT (readability-identifier-naming)
77 const std::string ObjectClassName::Global = "global";                  // NOLINT (readability-identifier-naming)
78 const std::string ObjectClassName::Generator = "Generator";            // NOLINT (readability-identifier-naming)
79 
80 const std::string RemoteObject::ObjectDescription = "Object";    // NOLINT (readability-identifier-naming)
81 const std::string RemoteObject::GlobalDescription = "global";    // NOLINT (readability-identifier-naming)
82 const std::string RemoteObject::ProxyDescription = "Proxy";      // NOLINT (readability-identifier-naming)
83 const std::string RemoteObject::PromiseDescription = "Promise";  // NOLINT (readability-identifier-naming)
84 const std::string RemoteObject::ArrayIteratorDescription =       // NOLINT (readability-identifier-naming)
85     "ArrayIterator";
86 const std::string RemoteObject::StringIteratorDescription =  // NOLINT (readability-identifier-naming)
87     "StringIterator";
88 const std::string RemoteObject::SetIteratorDescription = "SetIterator";  // NOLINT (readability-identifier-naming)
89 const std::string RemoteObject::MapIteratorDescription = "MapIterator";  // NOLINT (readability-identifier-naming)
90 const std::string RemoteObject::WeakRefDescription = "WeakRef";          // NOLINT (readability-identifier-naming)
91 const std::string RemoteObject::WeakMapDescription = "WeakMap";          // NOLINT (readability-identifier-naming)
92 const std::string RemoteObject::WeakSetDescription = "WeakSet";          // NOLINT (readability-identifier-naming)
93 const std::string RemoteObject::DataViewDescription = "DataView";          // NOLINT (readability-identifier-naming)
94 const std::string RemoteObject::JSPrimitiveNumberDescription =           // NOLINT (readability-identifier-naming)
95     "Number";
96 const std::string RemoteObject::JSPrimitiveBooleanDescription =          // NOLINT (readability-identifier-naming)
97     "Boolean";
98 const std::string RemoteObject::JSPrimitiveStringDescription =           // NOLINT (readability-identifier-naming)
99     "String";
100 const std::string RemoteObject::JSPrimitiveSymbolDescription =           // NOLINT (readability-identifier-naming)
101     "Symbol";
102 const std::string RemoteObject::DateTimeFormatDescription =                // NOLINT (readability-identifier-naming)
103     "DateTimeFormat";
104 const std::string RemoteObject::JSIntlDescription = "Intl";                // NOLINT (readability-identifier-naming)
105 const std::string RemoteObject::NumberFormatDescription = "NumberFormat";  // NOLINT (readability-identifier-naming)
106 const std::string RemoteObject::CollatorDescription = "Collator";          // NOLINT (readability-identifier-naming)
107 const std::string RemoteObject::PluralRulesDescription = "PluralRules";    // NOLINT (readability-identifier-naming)
108 const std::string RemoteObject::JSLocaleDescription = "Locale";            // NOLINT (readability-identifier-naming)
109 const std::string RemoteObject::JSListFormatDescription = "ListFormat";    // NOLINT (readability-identifier-naming)
110 const std::string RemoteObject::JSRelativeTimeFormatDescription =          // NOLINT (readability-identifier-naming)
111     "RelativeTimeFormat";
112 
FromTagged(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)113 std::unique_ptr<RemoteObject> RemoteObject::FromTagged(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
114 {
115     if (tagged->IsNull() || tagged->IsUndefined() ||
116         tagged->IsBoolean() || tagged->IsNumber() ||
117         tagged->IsBigInt()) {
118         return std::make_unique<PrimitiveRemoteObject>(ecmaVm, tagged);
119     }
120     if (tagged->IsString()) {
121         return std::make_unique<StringRemoteObject>(ecmaVm, Local<StringRef>(tagged));
122     }
123     if (tagged->IsSymbol()) {
124         return std::make_unique<SymbolRemoteObject>(ecmaVm, Local<SymbolRef>(tagged));
125     }
126     // proxy must be placed in front of all object types
127     if (tagged->IsProxy()) {
128         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Proxy, ObjectSubType::Proxy);
129     }
130     if (tagged->IsGeneratorFunction()) {
131         return std::make_unique<GeneratorFunctionRemoteObject>(ecmaVm, Local<SymbolRef>(tagged));
132     }
133     if (tagged->IsFunction()) {
134         return std::make_unique<FunctionRemoteObject>(ecmaVm, tagged);
135     }
136     if (tagged->IsArray(ecmaVm)) {
137         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Array, ObjectSubType::Array);
138     }
139     if (tagged->IsRegExp()) {
140         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Regexp, ObjectSubType::Regexp);
141     }
142     if (tagged->IsDate()) {
143         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Date, ObjectSubType::Date);
144     }
145     if (tagged->IsMap()) {
146         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Map, ObjectSubType::Map);
147     }
148     if (tagged->IsWeakMap()) {
149         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Weakmap, ObjectSubType::Weakmap);
150     }
151     if (tagged->IsSet()) {
152         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Set, ObjectSubType::Set);
153     }
154     if (tagged->IsWeakSet()) {
155         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Weakset, ObjectSubType::Weakset);
156     }
157     if (tagged->IsDataView()) {
158         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Dataview, ObjectSubType::Dataview);
159     }
160     if (tagged->IsError()) {
161         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Error, ObjectSubType::Error);
162     }
163     if (tagged->IsPromise()) {
164         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Promise, ObjectSubType::Promise);
165     }
166     if (tagged->IsArrayBuffer()) {
167         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Arraybuffer,
168             ObjectSubType::Arraybuffer);
169     }
170     if (tagged->IsArrayIterator()) {
171         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::ArrayIterator);
172     }
173     if (tagged->IsStringIterator()) {
174         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::StringIterator);
175     }
176     if (tagged->IsSetIterator()) {
177         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::SetIterator,
178             ObjectSubType::Iterator);
179     }
180     if (tagged->IsMapIterator()) {
181         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::MapIterator,
182             ObjectSubType::Iterator);
183     }
184     if (tagged->IsArrayList()) {
185         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
186     }
187     if (tagged->IsDeque()) {
188         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
189     }
190     if (tagged->IsHashMap()) {
191         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
192     }
193     if (tagged->IsHashSet()) {
194         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
195     }
196     if (tagged->IsLightWeightMap()) {
197         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
198     }
199     if (tagged->IsLightWeightSet()) {
200         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
201     }
202     if (tagged->IsLinkedList()) {
203         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
204     }
205     if (tagged->IsList()) {
206         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
207     }
208     if (tagged->IsPlainArray()) {
209         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
210     }
211     if (tagged->IsQueue()) {
212         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
213     }
214     if (tagged->IsStack()) {
215         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
216     }
217     if (tagged->IsTreeMap()) {
218         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
219     }
220     if (tagged->IsTreeSet()) {
221         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
222     }
223     if (tagged->IsVector()) {
224         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
225     }
226     if (tagged->IsObject()) {
227         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
228     }
229     std::unique_ptr<RemoteObject> object = std::make_unique<RemoteObject>();
230     object->SetType(ObjectType::Undefined);
231     return object;
232 }
233 
PrimitiveRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)234 PrimitiveRemoteObject::PrimitiveRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
235 {
236     if (tagged->IsNull()) {
237         SetType(ObjectType::Object).SetSubType(ObjectSubType::Null);
238     } else if (tagged->IsBoolean()) {
239         std::string description = tagged->IsTrue() ? "true" : "false";
240         SetType(ObjectType::Boolean)
241             .SetValue(tagged)
242             .SetUnserializableValue(description)
243             .SetDescription(description);
244     } else if (tagged->IsUndefined()) {
245         SetType(ObjectType::Undefined);
246     } else if (tagged->IsNumber()) {
247         std::string description = tagged->ToString(ecmaVm)->ToString();
248         SetType(ObjectType::Number)
249             .SetValue(tagged)
250             .SetUnserializableValue(description)
251             .SetDescription(description);
252     } else if (tagged->IsBigInt()) {
253         std::string description = tagged->ToString(ecmaVm)->ToString() + "n";  // n : BigInt literal postfix
254         SetType(ObjectType::Bigint)
255             .SetValue(tagged)
256             .SetUnserializableValue(description)
257             .SetDescription(description);
258     }
259 }
260 
StringRemoteObject(const EcmaVM * ecmaVm,Local<StringRef> tagged)261 StringRemoteObject::StringRemoteObject([[maybe_unused]] const EcmaVM *ecmaVm, Local<StringRef> tagged)
262 {
263     std::string description = tagged->ToString();
264     SetType(RemoteObject::TypeName::String)
265         .SetValue(tagged)
266         .SetUnserializableValue(description)
267         .SetDescription(description);
268 }
269 
SymbolRemoteObject(const EcmaVM * ecmaVm,Local<SymbolRef> tagged)270 SymbolRemoteObject::SymbolRemoteObject(const EcmaVM *ecmaVm, Local<SymbolRef> tagged)
271 {
272     std::string description = DescriptionForSymbol(ecmaVm, tagged);
273     SetType(RemoteObject::TypeName::Symbol)
274         .SetValue(tagged)
275         .SetUnserializableValue(description)
276         .SetDescription(description);
277 }
278 
FunctionRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)279 FunctionRemoteObject::FunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
280 {
281     std::string description = DescriptionForFunction(ecmaVm, tagged);
282     SetType(RemoteObject::TypeName::Function)
283         .SetClassName(RemoteObject::ClassName::Function)
284         .SetValue(tagged)
285         .SetUnserializableValue(description)
286         .SetDescription(description);
287 }
288 
GeneratorFunctionRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)289 GeneratorFunctionRemoteObject::GeneratorFunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
290 {
291     std::string description = DescriptionForGeneratorFunction(ecmaVm, tagged);
292     SetType(RemoteObject::TypeName::Function)
293         .SetClassName(RemoteObject::ClassName::Generator)
294         .SetValue(tagged)
295         .SetUnserializableValue(description)
296         .SetDescription(description);
297 }
298 
ObjectRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged,const std::string & classname)299 ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
300                                        const std::string &classname)
301 {
302     std::string description = DescriptionForObject(ecmaVm, tagged);
303     SetType(RemoteObject::TypeName::Object)
304         .SetClassName(classname)
305         .SetValue(tagged)
306         .SetUnserializableValue(description)
307         .SetDescription(description);
308 }
309 
ObjectRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged,const std::string & classname,const std::string & subtype)310 ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
311                                        const std::string &classname, const std::string &subtype)
312 {
313     std::string description = DescriptionForObject(ecmaVm, tagged);
314     SetType(RemoteObject::TypeName::Object)
315         .SetSubType(subtype)
316         .SetClassName(classname)
317         .SetValue(tagged)
318         .SetUnserializableValue(description)
319         .SetDescription(description);
320 }
321 
DescriptionForObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)322 std::string ObjectRemoteObject::DescriptionForObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
323 {
324     // proxy must be placed in front of all object types
325     if (tagged->IsProxy()) {
326         return RemoteObject::ProxyDescription;
327     }
328     if (tagged->IsArray(ecmaVm)) {
329         return DescriptionForArray(ecmaVm, Local<ArrayRef>(tagged));
330     }
331     if (tagged->IsRegExp()) {
332         return DescriptionForRegexp(ecmaVm, Local<RegExpRef>(tagged));
333     }
334     if (tagged->IsDate()) {
335         return DescriptionForDate(ecmaVm, Local<DateRef>(tagged));
336     }
337     if (tagged->IsMap()) {
338         return DescriptionForMap(ecmaVm, Local<MapRef>(tagged));
339     }
340     if (tagged->IsWeakMap()) {
341         return DescriptionForWeakMap(ecmaVm, Local<WeakMapRef>(tagged));
342     }
343     if (tagged->IsSet()) {
344         return DescriptionForSet(ecmaVm, Local<SetRef>(tagged));
345     }
346     if (tagged->IsWeakSet()) {
347         return DescriptionForWeakSet(ecmaVm, Local<WeakSetRef>(tagged));
348     }
349     if (tagged->IsDataView()) {
350         return DescriptionForDataView(Local<DataViewRef>(tagged));
351     }
352     if (tagged->IsError()) {
353         return DescriptionForError(ecmaVm, tagged);
354     }
355     if (tagged->IsPromise()) {
356         return RemoteObject::PromiseDescription;
357     }
358     if (tagged->IsArrayIterator()) {
359         return DescriptionForArrayIterator();
360     }
361     if (tagged->IsStringIterator()) {
362         return RemoteObject::StringIteratorDescription;
363     }
364     if (tagged->IsSetIterator()) {
365         return DescriptionForSetIterator();
366     }
367     if (tagged->IsMapIterator()) {
368         return DescriptionForMapIterator();
369     }
370     if (tagged->IsArrayBuffer()) {
371         return DescriptionForArrayBuffer(ecmaVm, Local<ArrayBufferRef>(tagged));
372     }
373     if (tagged->IsSharedArrayBuffer()) {
374         return DescriptionForSharedArrayBuffer(ecmaVm, Local<ArrayBufferRef>(tagged));
375     }
376     if (tagged->IsUint8Array()) {
377         return DescriptionForUint8Array(ecmaVm, Local<TypedArrayRef>(tagged));
378     }
379     if (tagged->IsInt8Array()) {
380         return DescriptionForInt8Array(ecmaVm, Local<TypedArrayRef>(tagged));
381     }
382     if (tagged->IsInt16Array()) {
383         return DescriptionForInt16Array(ecmaVm, Local<TypedArrayRef>(tagged));
384     }
385     if (tagged->IsInt32Array()) {
386         return DescriptionForInt32Array(ecmaVm, Local<TypedArrayRef>(tagged));
387     }
388     if (tagged->IsJSPrimitiveRef() && tagged->IsJSPrimitiveNumber()) {
389         return DescriptionForPrimitiveNumber(ecmaVm, tagged);
390     }
391     if (tagged->IsJSPrimitiveRef() && tagged->IsJSPrimitiveString()) {
392         return DescriptionForPrimitiveString(ecmaVm, tagged);
393     }
394     if (tagged->IsJSPrimitiveRef() && tagged->IsJSPrimitiveBoolean()) {
395         return DescriptionForPrimitiveBoolean(ecmaVm, tagged);
396     }
397     if (tagged->IsGeneratorObject()) {
398         return DescriptionForGeneratorObject(ecmaVm, tagged);
399     }
400     if (tagged->IsWeakRef()) {
401         return DescriptionForWeakRef();
402     }
403     if (tagged->IsJSLocale()) {
404         return DescriptionForJSLocale();
405     }
406     if (tagged->IsJSDateTimeFormat()) {
407         return DescriptionForDateTimeFormat();
408     }
409     if (tagged->IsJSRelativeTimeFormat()) {
410         return DescriptionForJSRelativeTimeFormat();
411     }
412     if (tagged->IsJSIntl()) {
413         return RemoteObject::JSIntlDescription;
414     }
415     if (tagged->IsJSNumberFormat()) {
416         return DescriptionForNumberFormat();
417     }
418     if (tagged->IsJSCollator()) {
419         return DescriptionForCollator();
420     }
421     if (tagged->IsJSPluralRules()) {
422         return DescriptionForPluralRules();
423     }
424     if (tagged->IsJSListFormat()) {
425         return DescriptionForJSListFormat();
426     }
427     if (tagged->IsArrayList()) {
428         return DescriptionForArrayList();
429     }
430     if (tagged->IsDeque()) {
431         return DescriptionForDeque();
432     }
433     if (tagged->IsHashMap()) {
434         return DescriptionForHashMap();
435     }
436     if (tagged->IsHashSet()) {
437         return DescriptionForHashSet();
438     }
439     if (tagged->IsLightWeightMap()) {
440         return DescriptionForLightWeightMap();
441     }
442     if (tagged->IsLightWeightSet()) {
443         return DescriptionForLightWeightSet();
444     }
445     if (tagged->IsLinkedList()) {
446         return DescriptionForLinkedList();
447     }
448     if (tagged->IsList()) {
449         return DescriptionForList();
450     }
451     if (tagged->IsPlainArray()) {
452         return DescriptionForPlainArray();
453     }
454     if (tagged->IsQueue()) {
455         return DescriptionForQueue();
456     }
457     if (tagged->IsStack()) {
458         return DescriptionForStack();
459     }
460     if (tagged->IsTreeMap()) {
461         return DescriptionForTreeMap();
462     }
463     if (tagged->IsTreeSet()) {
464         return DescriptionForTreeSet();
465     }
466     if (tagged->IsVector()) {
467         return DescriptionForVector();
468     }
469     return RemoteObject::ObjectDescription;
470 }
471 
DescriptionForArray(const EcmaVM * ecmaVm,Local<ArrayRef> tagged)472 std::string ObjectRemoteObject::DescriptionForArray(const EcmaVM *ecmaVm, Local<ArrayRef> tagged)
473 {
474     std::string description = "Array(" + std::to_string(tagged->Length(ecmaVm)) + ")";
475     return description;
476 }
477 
DescriptionForRegexp(const EcmaVM * ecmaVm,Local<RegExpRef> tagged)478 std::string ObjectRemoteObject::DescriptionForRegexp(const EcmaVM *ecmaVm, Local<RegExpRef> tagged)
479 {
480     std::string regExpSource = tagged->GetOriginalSource(ecmaVm)->ToString();
481     std::string regExpFlags = tagged->GetOriginalFlags();
482     return "/" + regExpSource + "/" + regExpFlags;
483 }
484 
DescriptionForDate(const EcmaVM * ecmaVm,Local<DateRef> tagged)485 std::string ObjectRemoteObject::DescriptionForDate(const EcmaVM *ecmaVm, Local<DateRef> tagged)
486 {
487     std::string description = tagged->ToString(ecmaVm)->ToString();
488     return description;
489 }
490 
DescriptionForMap(const EcmaVM * ecmaVm,Local<MapRef> tagged)491 std::string ObjectRemoteObject::DescriptionForMap(const EcmaVM *ecmaVm, Local<MapRef> tagged)
492 {
493     int32_t len = tagged->GetTotalElements();
494     int32_t index = 0;
495     std::string description = "Map(" + std::to_string(tagged->GetSize()) + ")";
496     if (!len) {
497         return description;
498     }
499     description += " {";
500     char cPre = '\'';
501     for (int32_t i = 0; i < len; ++i) {
502         // add Key
503         Local<JSValueRef> jsVKey = tagged->GetKey(ecmaVm, i);
504         if (jsVKey->IsHole()) {
505             continue;
506         }
507 
508         Local<JSValueRef> jsVValue = tagged->GetValue(ecmaVm, i);
509         if (jsVKey->IsObject()) {
510             description += "Object";
511         } else if (jsVKey->IsString()) {
512             description += cPre + jsVKey->ToString(ecmaVm)->ToString() + cPre;
513         } else {
514             description += jsVKey->ToString(ecmaVm)->ToString();
515         }
516 
517         description += " => ";
518         // add Value
519         if (jsVValue->IsObject()) {
520             description += "Object";
521         } else if (jsVValue->IsString()) {
522             description += cPre + jsVValue->ToString(ecmaVm)->ToString() + cPre;
523         } else {
524             description += jsVValue->ToString(ecmaVm)->ToString();
525         }
526         if (index == tagged->GetSize() - 1 || index >= 4) { // 4:The count of elements
527             description += tagged->GetSize() > 5 ? ", ..." : ""; // 5:The count of elements
528             break;
529         }
530         description += ", ";
531         index++;
532     }
533     description += "}";
534     return description;
535 }
536 
DescriptionForWeakMap(const EcmaVM * ecmaVm,Local<WeakMapRef> tagged)537 std::string ObjectRemoteObject::DescriptionForWeakMap(const EcmaVM *ecmaVm, Local<WeakMapRef> tagged)
538 {
539     int32_t len = tagged->GetTotalElements();
540     int32_t index = 0;
541     std::string description = "WeakMap(" + std::to_string(tagged->GetSize()) + ")";
542     if (!len) {
543         return description;
544     }
545     description += " {";
546     char cPre = '\'';
547     for (int32_t i = 0; i < len; ++i) {
548         Local<JSValueRef> jsVKey = tagged->GetKey(ecmaVm, i);
549         if (jsVKey->IsHole()) {
550             continue;
551         }
552         Local<JSValueRef> jsVValue = tagged->GetValue(ecmaVm, i);
553         if (jsVKey->IsObject()) {
554             description += "Object";
555         } else if (jsVKey->IsString()) {
556             description += cPre + jsVKey->ToString(ecmaVm)->ToString() + cPre;
557         } else {
558             description += jsVKey->ToString(ecmaVm)->ToString();
559         }
560 
561         description += " => ";
562 
563         if (jsVValue->IsObject()) {
564             description += "Object";
565         } else if (jsVValue->IsString()) {
566             description += cPre + jsVValue->ToString(ecmaVm)->ToString() + cPre;
567         } else {
568             description += jsVValue->ToString(ecmaVm)->ToString();
569         }
570         if (index == tagged->GetSize() - 1 || index >= 4) { // 4:The count of elements
571             description += tagged->GetSize() > 5 ? ", ..." : ""; // 5:The count of elements
572             break;
573         }
574         description += ", ";
575         index++;
576     }
577     description += "}";
578     return description;
579 }
580 
DescriptionForSet(const EcmaVM * ecmaVm,Local<SetRef> tagged)581 std::string ObjectRemoteObject::DescriptionForSet(const EcmaVM *ecmaVm, Local<SetRef> tagged)
582 {
583     int32_t len = tagged->GetTotalElements();
584     int32_t index = 0;
585     std::string description = ("Set(" + std::to_string(tagged->GetSize()) + ")");
586     if (!len) {
587         return description;
588     }
589     description += " {";
590     char cPre = '\'';
591     for (int32_t i = 0; i < len; ++i) {
592         // add Key
593         Local<JSValueRef> jsValue = tagged->GetValue(ecmaVm, i);
594         if (jsValue->IsHole()) {
595             continue;
596         }
597         // add Value
598         if (jsValue->IsObject()) {
599             description += "Object";
600         } else if (jsValue->IsString()) {
601             description += cPre + jsValue->ToString(ecmaVm)->ToString() + cPre;
602         } else {
603             description += jsValue->ToString(ecmaVm)->ToString();
604         }
605         if (index == tagged->GetSize() - 1 || index >= 4) { // 4:The count of elements
606             description += tagged->GetSize() > 5 ? ", ..." : ""; // 5:The count of elements
607             break;
608         }
609         description += ", ";
610         index++;
611     }
612     description += "}";
613     return description;
614 }
615 
DescriptionForWeakSet(const EcmaVM * ecmaVm,Local<WeakSetRef> tagged)616 std::string ObjectRemoteObject::DescriptionForWeakSet(const EcmaVM *ecmaVm, Local<WeakSetRef> tagged)
617 {
618     int32_t len = tagged->GetTotalElements();
619     int32_t index = 0;
620     std::string description = ("WeakSet(" + std::to_string(tagged->GetSize()) + ")");
621     if (!len) {
622         return description;
623     }
624     description += " {";
625     char cPre = '\'';
626     for (int32_t i = 0; i < len; ++i) {
627         Local<JSValueRef> jsValue = tagged->GetValue(ecmaVm, i);
628         if (jsValue->IsHole()) {
629             continue;
630         }
631         if (jsValue->IsObject()) {
632             description += "Object";
633         } else if (jsValue->IsString()) {
634             description += cPre + jsValue->ToString(ecmaVm)->ToString() + cPre;
635         } else {
636             description += jsValue->ToString(ecmaVm)->ToString();
637         }
638         if (index == tagged->GetSize() - 1 || index >= 4) { // 4:The count of elements
639             description += tagged->GetSize() > 5 ? ", ..." : ""; // 5:The count of elements
640             break;
641         }
642         description += ", ";
643         index++;
644     }
645     description += "}";
646     return description;
647 }
648 
DescriptionForDataView(Local<DataViewRef> tagged)649 std::string ObjectRemoteObject::DescriptionForDataView(Local<DataViewRef> tagged)
650 {
651     std::string description = ("DataView(" + std::to_string(tagged->ByteLength()) + ")");
652     return description;
653 }
654 
DescriptionForError(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)655 std::string ObjectRemoteObject::DescriptionForError(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
656 {
657     // add name
658     Local<JSValueRef> name = StringRef::NewFromUtf8(ecmaVm, "name");
659     std::string strName = Local<ObjectRef>(tagged)->Get(ecmaVm, name)->ToString(ecmaVm)->ToString();
660     // add message
661     Local<JSValueRef> message = StringRef::NewFromUtf8(ecmaVm, "message");
662     std::string strMessage = Local<ObjectRef>(tagged)->Get(ecmaVm, message)->ToString(ecmaVm)->ToString();
663     if (strMessage.empty()) {
664         return strName;
665     } else {
666         return strName + ": " + strMessage;
667     }
668 }
669 
DescriptionForArrayIterator()670 std::string ObjectRemoteObject::DescriptionForArrayIterator()
671 {
672     std::string description = RemoteObject::ArrayIteratorDescription + "{}";
673     return description;
674 }
675 
DescriptionForSetIterator()676 std::string ObjectRemoteObject::DescriptionForSetIterator()
677 {
678     std::string description = RemoteObject::SetIteratorDescription + "{}";
679     return description;
680 }
681 
DescriptionForMapIterator()682 std::string ObjectRemoteObject::DescriptionForMapIterator()
683 {
684     std::string description = RemoteObject::MapIteratorDescription + "{}";
685     return description;
686 }
687 
DescriptionForArrayBuffer(const EcmaVM * ecmaVm,Local<ArrayBufferRef> tagged)688 std::string ObjectRemoteObject::DescriptionForArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)
689 {
690     int32_t len = tagged->ByteLength(ecmaVm);
691     std::string description = ("ArrayBuffer(" + std::to_string(len) + ")");
692     return description;
693 }
694 
DescriptionForSharedArrayBuffer(const EcmaVM * ecmaVm,Local<ArrayBufferRef> tagged)695 std::string ObjectRemoteObject::DescriptionForSharedArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)
696 {
697     int32_t len = tagged->ByteLength(ecmaVm);
698     std::string description = ("SharedArrayBuffer(" + std::to_string(len) + ")");
699     return description;
700 }
701 
DescriptionForUint8Array(const EcmaVM * ecmaVm,Local<TypedArrayRef> tagged)702 std::string ObjectRemoteObject::DescriptionForUint8Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
703 {
704     int32_t len = static_cast<int32_t>(tagged->ByteLength(ecmaVm));
705     std::string description = ("Uint8Array(" + std::to_string(len) + ")");
706     return description;
707 }
708 
DescriptionForInt8Array(const EcmaVM * ecmaVm,Local<TypedArrayRef> tagged)709 std::string ObjectRemoteObject::DescriptionForInt8Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
710 {
711     int32_t len = static_cast<int32_t>(tagged->ByteLength(ecmaVm));
712     std::string description = ("Int8Array(" + std::to_string(len) + ")");
713     return description;
714 }
715 
DescriptionForInt16Array(const EcmaVM * ecmaVm,Local<TypedArrayRef> tagged)716 std::string ObjectRemoteObject::DescriptionForInt16Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
717 {
718     int32_t len = tagged->ByteLength(ecmaVm) / static_cast<int32_t>(NumberSize::BYTES_OF_16BITS);
719     std::string description = ("Int16Array(" + std::to_string(len) + ")");
720     return description;
721 }
722 
DescriptionForInt32Array(const EcmaVM * ecmaVm,Local<TypedArrayRef> tagged)723 std::string ObjectRemoteObject::DescriptionForInt32Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
724 {
725     int32_t len = tagged->ByteLength(ecmaVm) / static_cast<int32_t>(NumberSize::BYTES_OF_32BITS);
726     std::string description = ("Int32Array(" + std::to_string(len) + ")");
727     return description;
728 }
729 
DescriptionForPrimitiveNumber(const EcmaVM * ecmaVm,const Local<JSValueRef> & tagged)730 std::string ObjectRemoteObject::DescriptionForPrimitiveNumber(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
731 {
732     std::string strValue = tagged->ToString(ecmaVm)->ToString();
733     std::string description = RemoteObject::JSPrimitiveNumberDescription + "{[[PrimitiveValue]]: " + strValue + "}";
734     return description;
735 }
736 
DescriptionForPrimitiveString(const EcmaVM * ecmaVm,const Local<JSValueRef> & tagged)737 std::string ObjectRemoteObject::DescriptionForPrimitiveString(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
738 {
739     std::string strValue = tagged->ToString(ecmaVm)->ToString();
740     std::string description = RemoteObject::JSPrimitiveStringDescription + "{[[PrimitiveValue]]: " + strValue + "}";
741     return description;
742 }
743 
DescriptionForPrimitiveBoolean(const EcmaVM * ecmaVm,const Local<JSValueRef> & tagged)744 std::string ObjectRemoteObject::DescriptionForPrimitiveBoolean(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
745 {
746     std::string strValue = tagged->ToString(ecmaVm)->ToString();
747     std::string description = RemoteObject::JSPrimitiveBooleanDescription + "{[[PrimitiveValue]]: " + strValue + "}";
748     return description;
749 }
750 
DescriptionForGeneratorObject(const EcmaVM * ecmaVm,const Local<JSValueRef> & tagged)751 std::string ObjectRemoteObject::DescriptionForGeneratorObject(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
752 {
753     Local<GeneratorObjectRef> genObjectRef = tagged->ToObject(ecmaVm);
754     // add Status
755     Local<JSValueRef> jsValueRef = genObjectRef->GetGeneratorState(ecmaVm);
756     std::string strState = genObjectRef->GetGeneratorState(ecmaVm)->ToString(ecmaVm)->ToString();
757     // add FuncName
758     jsValueRef = genObjectRef->GetGeneratorFunction(ecmaVm);
759     Local<JSValueRef> name = StringRef::NewFromUtf8(ecmaVm, "name");
760     std::string strFuncName = Local<ObjectRef>(jsValueRef)->Get(ecmaVm, name)->ToString(ecmaVm)->ToString();
761 
762     std::string description = strFuncName + " {<" + strState + ">}";
763     return description;
764 }
765 
DescriptionForWeakRef()766 std::string ObjectRemoteObject::DescriptionForWeakRef()
767 {
768     std::string description = RemoteObject::WeakRefDescription + " {}";
769     return description;
770 }
771 
DescriptionForDateTimeFormat()772 std::string ObjectRemoteObject::DescriptionForDateTimeFormat()
773 {
774     std::string description = RemoteObject::DateTimeFormatDescription + " {}";
775     return description;
776 }
777 
DescriptionForNumberFormat()778 std::string ObjectRemoteObject::DescriptionForNumberFormat()
779 {
780     std::string description = RemoteObject::NumberFormatDescription + " {}";
781     return description;
782 }
783 
DescriptionForCollator()784 std::string ObjectRemoteObject::DescriptionForCollator()
785 {
786     std::string description = RemoteObject::CollatorDescription + " {}";
787     return description;
788 }
789 
DescriptionForPluralRules()790 std::string ObjectRemoteObject::DescriptionForPluralRules()
791 {
792     std::string description = RemoteObject::PluralRulesDescription + " {}";
793     return description;
794 }
795 
DescriptionForJSLocale()796 std::string ObjectRemoteObject::DescriptionForJSLocale()
797 {
798     std::string description = RemoteObject::JSLocaleDescription + " {}";
799     return description;
800 }
801 
DescriptionForJSRelativeTimeFormat()802 std::string ObjectRemoteObject::DescriptionForJSRelativeTimeFormat()
803 {
804     std::string description = RemoteObject::JSRelativeTimeFormatDescription + " {}";
805     return description;
806 }
807 
DescriptionForJSListFormat()808 std::string ObjectRemoteObject::DescriptionForJSListFormat()
809 {
810     std::string description = RemoteObject::JSListFormatDescription + " {}";
811     return description;
812 }
813 
DescriptionForArrayList()814 std::string ObjectRemoteObject::DescriptionForArrayList()
815 {
816     std::string description = "ArrayList";
817     return description;
818 }
819 
DescriptionForDeque()820 std::string ObjectRemoteObject::DescriptionForDeque()
821 {
822     std::string description = "Deque";
823     return description;
824 }
825 
DescriptionForHashMap()826 std::string ObjectRemoteObject::DescriptionForHashMap()
827 {
828     std::string description = "HashMap";
829     return description;
830 }
831 
DescriptionForHashSet()832 std::string ObjectRemoteObject::DescriptionForHashSet()
833 {
834     std::string description = "HashSet";
835     return description;
836 }
837 
DescriptionForLightWeightMap()838 std::string ObjectRemoteObject::DescriptionForLightWeightMap()
839 {
840     std::string description = "LightWeightMap";
841     return description;
842 }
843 
DescriptionForLightWeightSet()844 std::string ObjectRemoteObject::DescriptionForLightWeightSet()
845 {
846     std::string description = "LightWeightSet";
847     return description;
848 }
849 
DescriptionForLinkedList()850 std::string ObjectRemoteObject::DescriptionForLinkedList()
851 {
852     std::string description = "LinkedList";
853     return description;
854 }
855 
DescriptionForList()856 std::string ObjectRemoteObject::DescriptionForList()
857 {
858     std::string description = "List";
859     return description;
860 }
861 
DescriptionForPlainArray()862 std::string ObjectRemoteObject::DescriptionForPlainArray()
863 {
864     std::string description = "PlainArray";
865     return description;
866 }
867 
DescriptionForQueue()868 std::string ObjectRemoteObject::DescriptionForQueue()
869 {
870     std::string description = "Queue";
871     return description;
872 }
873 
DescriptionForStack()874 std::string ObjectRemoteObject::DescriptionForStack()
875 {
876     std::string description = "Stack";
877     return description;
878 }
879 
DescriptionForTreeMap()880 std::string ObjectRemoteObject::DescriptionForTreeMap()
881 {
882     std::string description = "TreeMap";
883     return description;
884 }
885 
DescriptionForTreeSet()886 std::string ObjectRemoteObject::DescriptionForTreeSet()
887 {
888     std::string description = "TreeSet";
889     return description;
890 }
891 
DescriptionForVector()892 std::string ObjectRemoteObject::DescriptionForVector()
893 {
894     std::string description = "Vector";
895     return description;
896 }
897 
DescriptionForSymbol(const EcmaVM * ecmaVm,Local<SymbolRef> tagged) const898 std::string SymbolRemoteObject::DescriptionForSymbol(const EcmaVM *ecmaVm, Local<SymbolRef> tagged) const
899 {
900     std::string description = "Symbol(" + tagged->GetDescription(ecmaVm)->ToString() + ")";
901     return description;
902 }
903 
DescriptionForFunction(const EcmaVM * ecmaVm,Local<FunctionRef> tagged) const904 std::string FunctionRemoteObject::DescriptionForFunction(const EcmaVM *ecmaVm, Local<FunctionRef> tagged) const
905 {
906     std::string sourceCode;
907     if (tagged->IsNative(ecmaVm)) {
908         sourceCode = "[native code]";
909     } else {
910         sourceCode = "[js code]";
911     }
912     Local<StringRef> name = tagged->GetName(ecmaVm);
913     std::string description = "function " + name->ToString() + "( { " + sourceCode + " }";
914     return description;
915 }
916 
DescriptionForGeneratorFunction(const EcmaVM * ecmaVm,Local<FunctionRef> tagged) const917 std::string GeneratorFunctionRemoteObject::DescriptionForGeneratorFunction(const EcmaVM *ecmaVm,
918     Local<FunctionRef> tagged) const
919 {
920     std::string sourceCode;
921     if (tagged->IsNative(ecmaVm)) {
922         sourceCode = "[native code]";
923     } else {
924         sourceCode = "[js code]";
925     }
926     Local<StringRef> name = tagged->GetName(ecmaVm);
927     std::string description = "function* " + name->ToString() + "( { " + sourceCode + " }";
928     return description;
929 }
930 
Create(const PtJson & params)931 std::unique_ptr<RemoteObject> RemoteObject::Create(const PtJson &params)
932 {
933     std::string error;
934     auto remoteObject = std::make_unique<RemoteObject>();
935     Result ret;
936 
937     std::string type;
938     ret = params.GetString("type", &type);
939     if (ret == Result::SUCCESS) {
940         if (ObjectType::Valid(type)) {
941             remoteObject->type_ = std::move(type);
942         } else {
943             error += "'type' is invalid;";
944         }
945     } else {
946         error += "Unknown 'type';";
947     }
948 
949     std::string subType;
950     ret = params.GetString("subtype", &subType);
951     if (ret == Result::SUCCESS) {
952         if (ObjectSubType::Valid(subType)) {
953             remoteObject->subType_ = std::move(subType);
954         } else {
955             error += "'subtype' is invalid;";
956         }
957     } else if (ret == Result::TYPE_ERROR) {
958         error += "Unknown 'subtype';";
959     }
960 
961     std::string className;
962     ret = params.GetString("className", &className);
963     if (ret == Result::SUCCESS) {
964         remoteObject->className_ = std::move(className);
965     } else if (ret == Result::TYPE_ERROR) {
966         error += "Unknown 'className';";
967     }
968 
969     std::string unserializableValue;
970     ret = params.GetString("unserializableValue", &unserializableValue);
971     if (ret == Result::SUCCESS) {
972         remoteObject->unserializableValue_ = std::move(unserializableValue);
973     } else if (ret == Result::TYPE_ERROR) {
974         error += "Unknown 'unserializableValue';";
975     }
976 
977     std::string description;
978     ret = params.GetString("description", &description);
979     if (ret == Result::SUCCESS) {
980         remoteObject->description_ = std::move(description);
981     } else if (ret == Result::TYPE_ERROR) {
982         error += "Unknown 'description';";
983     }
984 
985     std::string objectId;
986     ret = params.GetString("objectId", &objectId);
987     if (ret == Result::SUCCESS) {
988         remoteObject->objectId_ = std::stoi(objectId);
989     } else if (ret == Result::TYPE_ERROR) {
990         error += "Unknown 'objectId';";
991     }
992 
993     if (!error.empty()) {
994         LOG_DEBUGGER(ERROR) << "RemoteObject::Create " << error;
995         return nullptr;
996     }
997 
998     return remoteObject;
999 }
1000 
ToJson() const1001 std::unique_ptr<PtJson> RemoteObject::ToJson() const
1002 {
1003     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1004 
1005     result->Add("type", type_.c_str());
1006     if (subType_) {
1007         result->Add("subtype", subType_->c_str());
1008     }
1009     if (className_) {
1010         result->Add("className", className_->c_str());
1011     }
1012     if (unserializableValue_) {
1013         result->Add("unserializableValue", unserializableValue_->c_str());
1014     }
1015     if (description_) {
1016         result->Add("description", description_->c_str());
1017     }
1018     if (objectId_) {
1019         result->Add("objectId", std::to_string(objectId_.value()).c_str());
1020     }
1021 
1022     return result;
1023 }
1024 
Create(const PtJson & params)1025 std::unique_ptr<ExceptionDetails> ExceptionDetails::Create(const PtJson &params)
1026 {
1027     std::string error;
1028     auto exceptionDetails = std::make_unique<ExceptionDetails>();
1029     Result ret;
1030 
1031     int32_t exceptionId;
1032     ret = params.GetInt("exceptionId", &exceptionId);
1033     if (ret == Result::SUCCESS) {
1034         exceptionDetails->exceptionId_ = exceptionId;
1035     } else {
1036         error += "Unknown 'exceptionId';";
1037     }
1038 
1039     std::string text;
1040     ret = params.GetString("text", &text);
1041     if (ret == Result::SUCCESS) {
1042         exceptionDetails->text_ = std::move(text);
1043     } else {
1044         error += "Unknown 'text';";
1045     }
1046 
1047     int32_t lineNumber;
1048     ret = params.GetInt("lineNumber", &lineNumber);
1049     if (ret == Result::SUCCESS) {
1050         exceptionDetails->lineNumber_ = lineNumber;
1051     } else {
1052         error += "Unknown 'lineNumber';";
1053     }
1054 
1055     int32_t columnNumber;
1056     ret = params.GetInt("columnNumber", &columnNumber);
1057     if (ret == Result::SUCCESS) {
1058         exceptionDetails->columnNumber_ = columnNumber;
1059     } else {
1060         error += "Unknown 'columnNumber';";
1061     }
1062 
1063     std::string scriptId;
1064     ret = params.GetString("scriptId", &scriptId);
1065     if (ret == Result::SUCCESS) {
1066         exceptionDetails->scriptId_ = std::stoi(scriptId);
1067     } else if (ret == Result::TYPE_ERROR) {
1068         error += "Unknown 'scriptId';";
1069     }
1070 
1071     std::string url;
1072     ret = params.GetString("url", &url);
1073     if (ret == Result::SUCCESS) {
1074         exceptionDetails->url_ = std::move(url);
1075     } else if (ret == Result::TYPE_ERROR) {
1076         error += "Unknown 'url';";
1077     }
1078 
1079     std::unique_ptr<PtJson> exception;
1080     ret = params.GetObject("exception", &exception);
1081     if (ret == Result::SUCCESS) {
1082         std::unique_ptr<RemoteObject> obj = RemoteObject::Create(*exception);
1083         if (obj == nullptr) {
1084             error += "'exception' format error;";
1085         } else {
1086             exceptionDetails->exception_ = std::move(obj);
1087         }
1088     } else if (ret == Result::TYPE_ERROR) {
1089         error += "Unknown 'exception';";
1090     }
1091 
1092     int32_t executionContextId;
1093     ret = params.GetInt("executionContextId", &executionContextId);
1094     if (ret == Result::SUCCESS) {
1095         exceptionDetails->executionContextId_ = executionContextId;
1096     } else if (ret == Result::TYPE_ERROR) {
1097         error += "Unknown 'executionContextId';";
1098     }
1099 
1100     if (!error.empty()) {
1101         LOG_DEBUGGER(ERROR) << "ExceptionDetails::Create " << error;
1102         return nullptr;
1103     }
1104 
1105     return exceptionDetails;
1106 }
1107 
ToJson() const1108 std::unique_ptr<PtJson> ExceptionDetails::ToJson() const
1109 {
1110     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1111 
1112     result->Add("exceptionId", exceptionId_);
1113     result->Add("text", text_.c_str());
1114     result->Add("lineNumber", lineNumber_);
1115     result->Add("columnNumber", columnNumber_);
1116 
1117     if (scriptId_) {
1118         result->Add("scriptId", std::to_string(scriptId_.value()).c_str());
1119     }
1120     if (url_) {
1121         result->Add("url", url_->c_str());
1122     }
1123     if (exception_) {
1124         ASSERT(exception_.value() != nullptr);
1125         result->Add("exception", exception_.value()->ToJson());
1126     }
1127     if (executionContextId_) {
1128         result->Add("executionContextId", executionContextId_.value());
1129     }
1130 
1131     return result;
1132 }
1133 
Create(const PtJson & params)1134 std::unique_ptr<InternalPropertyDescriptor> InternalPropertyDescriptor::Create(const PtJson &params)
1135 {
1136     std::string error;
1137     auto internalPropertyDescriptor = std::make_unique<InternalPropertyDescriptor>();
1138     Result ret;
1139 
1140     std::string name;
1141     ret = params.GetString("name", &name);
1142     if (ret == Result::SUCCESS) {
1143         internalPropertyDescriptor->name_ = std::move(name);
1144     } else {
1145         error += "Unknown 'name';";
1146     }
1147 
1148     std::unique_ptr<PtJson> value;
1149     ret = params.GetObject("value", &value);
1150     if (ret == Result::SUCCESS) {
1151         std::unique_ptr<RemoteObject> obj = RemoteObject::Create(*value);
1152         if (obj == nullptr) {
1153             error += "'value' format error;";
1154         } else {
1155             internalPropertyDescriptor->value_ = std::move(obj);
1156         }
1157     } else if (ret == Result::TYPE_ERROR) {
1158         error += "Unknown 'value';";
1159     }
1160 
1161     if (!error.empty()) {
1162         LOG_DEBUGGER(ERROR) << "InternalPropertyDescriptor::Create " << error;
1163         return nullptr;
1164     }
1165 
1166     return internalPropertyDescriptor;
1167 }
1168 
ToJson() const1169 std::unique_ptr<PtJson> InternalPropertyDescriptor::ToJson() const
1170 {
1171     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1172 
1173     result->Add("name", name_.c_str());
1174     if (value_) {
1175         ASSERT(value_.value() != nullptr);
1176         result->Add("value", value_.value()->ToJson());
1177     }
1178 
1179     return result;
1180 }
1181 
Create(const PtJson & params)1182 std::unique_ptr<PrivatePropertyDescriptor> PrivatePropertyDescriptor::Create(const PtJson &params)
1183 {
1184     std::string error;
1185     auto privatePropertyDescriptor = std::make_unique<PrivatePropertyDescriptor>();
1186     Result ret;
1187 
1188     std::string name;
1189     ret = params.GetString("name", &name);
1190     if (ret == Result::SUCCESS) {
1191         privatePropertyDescriptor->name_ = std::move(name);
1192     } else {
1193         error += "Unknown 'name';";
1194     }
1195 
1196     std::unique_ptr<PtJson> value;
1197     ret = params.GetObject("value", &value);
1198     std::unique_ptr<RemoteObject> obj;
1199     if (ret == Result::SUCCESS) {
1200         obj = RemoteObject::Create(*value);
1201         if (obj == nullptr) {
1202             error += "'value' format error;";
1203         } else {
1204             privatePropertyDescriptor->value_ = std::move(obj);
1205         }
1206     } else if (ret == Result::TYPE_ERROR) {
1207         error += "Unknown 'value';";
1208     }
1209 
1210     std::unique_ptr<PtJson> get;
1211     ret = params.GetObject("get", &get);
1212     if (ret == Result::SUCCESS) {
1213         obj = RemoteObject::Create(*get);
1214         if (obj == nullptr) {
1215             error += "'get' format error;";
1216         } else {
1217             privatePropertyDescriptor->get_ = std::move(obj);
1218         }
1219     } else if (ret == Result::TYPE_ERROR) {
1220         error += "Unknown 'get';";
1221     }
1222 
1223     std::unique_ptr<PtJson> set;
1224     ret = params.GetObject("set", &set);
1225     if (ret == Result::SUCCESS) {
1226         obj = RemoteObject::Create(*set);
1227         if (obj == nullptr) {
1228             error += "'set' format error;";
1229         } else {
1230             privatePropertyDescriptor->set_ = std::move(obj);
1231         }
1232     } else if (ret == Result::TYPE_ERROR) {
1233         error += "Unknown 'set';";
1234     }
1235 
1236     if (!error.empty()) {
1237         LOG_DEBUGGER(ERROR) << "PrivatePropertyDescriptor::Create " << error;
1238         return nullptr;
1239     }
1240 
1241     return privatePropertyDescriptor;
1242 }
1243 
ToJson() const1244 std::unique_ptr<PtJson> PrivatePropertyDescriptor::ToJson() const
1245 {
1246     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1247 
1248     result->Add("name", name_.c_str());
1249     if (value_) {
1250         ASSERT(value_.value() != nullptr);
1251         result->Add("value", value_.value()->ToJson());
1252     }
1253     if (get_) {
1254         ASSERT(get_.value() != nullptr);
1255         result->Add("get", get_.value()->ToJson());
1256     }
1257     if (set_) {
1258         ASSERT(set_.value() != nullptr);
1259         result->Add("set", set_.value()->ToJson());
1260     }
1261 
1262     return result;
1263 }
1264 
FromProperty(const EcmaVM * ecmaVm,Local<JSValueRef> name,const PropertyAttribute & property)1265 std::unique_ptr<PropertyDescriptor> PropertyDescriptor::FromProperty(const EcmaVM *ecmaVm,
1266     Local<JSValueRef> name, const PropertyAttribute &property)
1267 {
1268     std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
1269 
1270     std::string nameStr;
1271     if (name->IsSymbol()) {
1272         Local<SymbolRef> symbol(name);
1273         nameStr = "Symbol(" + Local<SymbolRef>(name)->GetDescription(ecmaVm)->ToString() + ")";
1274         debuggerProperty->symbol_ = RemoteObject::FromTagged(ecmaVm, name);
1275     } else {
1276         nameStr = name->ToString(ecmaVm)->ToString();
1277     }
1278 
1279     debuggerProperty->name_ = nameStr;
1280     if (property.HasValue()) {
1281         debuggerProperty->value_ = RemoteObject::FromTagged(ecmaVm, property.GetValue(ecmaVm));
1282     }
1283     if (property.HasWritable()) {
1284         debuggerProperty->writable_ = property.IsWritable();
1285     }
1286     if (property.HasGetter()) {
1287         debuggerProperty->get_ = RemoteObject::FromTagged(ecmaVm, property.GetGetter(ecmaVm));
1288     }
1289     if (property.HasSetter()) {
1290         debuggerProperty->set_ = RemoteObject::FromTagged(ecmaVm, property.GetSetter(ecmaVm));
1291     }
1292     debuggerProperty->configurable_ = property.IsConfigurable();
1293     debuggerProperty->enumerable_ = property.IsEnumerable();
1294     debuggerProperty->isOwn_ = true;
1295 
1296     return debuggerProperty;
1297 }
1298 
Create(const PtJson & params)1299 std::unique_ptr<PropertyDescriptor> PropertyDescriptor::Create(const PtJson &params)
1300 {
1301     std::string error;
1302     auto propertyDescriptor = std::make_unique<PropertyDescriptor>();
1303     Result ret;
1304 
1305     std::string name;
1306     ret = params.GetString("name", &name);
1307     if (ret == Result::SUCCESS) {
1308         propertyDescriptor->name_ = std::move(name);
1309     } else {
1310         error += "Unknown 'name';";
1311     }
1312 
1313     std::unique_ptr<PtJson> value;
1314     std::unique_ptr<RemoteObject> obj;
1315     ret = params.GetObject("value", &value);
1316     if (ret == Result::SUCCESS) {
1317         obj = RemoteObject::Create(*value);
1318         if (obj == nullptr) {
1319             error += "'value' format error;";
1320         } else {
1321             propertyDescriptor->value_ = std::move(obj);
1322         }
1323     } else if (ret == Result::TYPE_ERROR) {
1324         error += "Unknown 'value';";
1325     }
1326 
1327     bool writable = false;
1328     ret = params.GetBool("writable", &writable);
1329     if (ret == Result::SUCCESS) {
1330         propertyDescriptor->writable_ = writable;
1331     } else if (ret == Result::TYPE_ERROR) {
1332         error += "Unknown 'writable';";
1333     }
1334 
1335     std::unique_ptr<PtJson> get;
1336     ret = params.GetObject("get", &get);
1337     if (ret == Result::SUCCESS) {
1338         obj = RemoteObject::Create(*get);
1339         if (obj == nullptr) {
1340             error += "'get' format error;";
1341         } else {
1342             propertyDescriptor->get_ = std::move(obj);
1343         }
1344     } else if (ret == Result::TYPE_ERROR) {
1345         error += "Unknown 'get';";
1346     }
1347 
1348     std::unique_ptr<PtJson> set;
1349     ret = params.GetObject("set", &set);
1350     if (ret == Result::SUCCESS) {
1351         obj = RemoteObject::Create(*set);
1352         if (obj == nullptr) {
1353             error += "'set' format error;";
1354         } else {
1355             propertyDescriptor->set_ = std::move(obj);
1356         }
1357     } else if (ret == Result::TYPE_ERROR) {
1358         error += "Unknown 'set';";
1359     }
1360 
1361     bool configurable = false;
1362     ret = params.GetBool("configurable", &configurable);
1363     if (ret == Result::SUCCESS) {
1364         propertyDescriptor->configurable_ = configurable;
1365     } else if (ret == Result::TYPE_ERROR) {
1366         error += "Unknown 'configurable';";
1367     }
1368 
1369     bool enumerable = false;
1370     ret = params.GetBool("enumerable", &enumerable);
1371     if (ret == Result::SUCCESS) {
1372         propertyDescriptor->enumerable_ = enumerable;
1373     } else if (ret == Result::TYPE_ERROR) {
1374         error += "Unknown 'enumerable';";
1375     }
1376 
1377     bool wasThrown = false;
1378     ret = params.GetBool("wasThrown", &wasThrown);
1379     if (ret == Result::SUCCESS) {
1380         propertyDescriptor->wasThrown_ = wasThrown;
1381     } else if (ret == Result::TYPE_ERROR) {
1382         error += "Unknown 'wasThrown';";
1383     }
1384 
1385     bool isOwn = false;
1386     ret = params.GetBool("isOwn", &isOwn);
1387     if (ret == Result::SUCCESS) {
1388         propertyDescriptor->isOwn_ = isOwn;
1389     } else if (ret == Result::TYPE_ERROR) {
1390         error += "Unknown 'isOwn';";
1391     }
1392 
1393     std::unique_ptr<PtJson> symbol;
1394     ret = params.GetObject("symbol", &symbol);
1395     if (ret == Result::SUCCESS) {
1396         obj = RemoteObject::Create(*symbol);
1397         if (obj == nullptr) {
1398             error += "'symbol' format error;";
1399         } else {
1400             propertyDescriptor->symbol_ = std::move(obj);
1401         }
1402     } else if (ret == Result::TYPE_ERROR) {
1403         error += "Unknown 'symbol';";
1404     }
1405 
1406     if (!error.empty()) {
1407         LOG_DEBUGGER(ERROR) << "PropertyDescriptor::Create " << error;
1408         return nullptr;
1409     }
1410 
1411     return propertyDescriptor;
1412 }
1413 
ToJson() const1414 std::unique_ptr<PtJson> PropertyDescriptor::ToJson() const
1415 {
1416     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1417 
1418     result->Add("name", name_.c_str());
1419     if (value_) {
1420         ASSERT(value_.value() != nullptr);
1421         result->Add("value", value_.value()->ToJson());
1422     }
1423     if (writable_) {
1424         result->Add("writable", writable_.value());
1425     }
1426     if (get_) {
1427         ASSERT(get_.value() != nullptr);
1428         result->Add("get", get_.value()->ToJson());
1429     }
1430     if (set_) {
1431         ASSERT(set_.value() != nullptr);
1432         result->Add("set", set_.value()->ToJson());
1433     }
1434     result->Add("configurable", configurable_);
1435     result->Add("enumerable", enumerable_);
1436     if (wasThrown_) {
1437         result->Add("wasThrown", wasThrown_.value());
1438     }
1439     if (isOwn_) {
1440         result->Add("isOwn", isOwn_.value());
1441     }
1442     if (symbol_) {
1443         ASSERT(symbol_.value() != nullptr);
1444         result->Add("symbol", symbol_.value()->ToJson());
1445     }
1446 
1447     return result;
1448 }
1449 
Create(const PtJson & params)1450 std::unique_ptr<CallArgument> CallArgument::Create(const PtJson &params)
1451 {
1452     auto callArgument = std::make_unique<CallArgument>();
1453     std::string error;
1454     Result ret;
1455 
1456     std::string unserializableValue;
1457     ret = params.GetString("unserializableValue", &unserializableValue);
1458     if (ret == Result::SUCCESS) {
1459         callArgument->unserializableValue_ = std::move(unserializableValue);
1460     } else if (ret == Result::TYPE_ERROR) {  // optional value
1461         error += "Unknown 'unserializableValue';";
1462     }
1463     std::string objectId;
1464     ret = params.GetString("objectId", &objectId);
1465     if (ret == Result::SUCCESS) {
1466         callArgument->objectId_ = std::stoi(objectId);
1467     } else if (ret == Result::TYPE_ERROR) {  // optional value
1468         error += "Unknown 'objectId';";
1469     }
1470 
1471     if (!error.empty()) {
1472         LOG_DEBUGGER(ERROR) << "CallArgument::Create " << error;
1473         return nullptr;
1474     }
1475 
1476     return callArgument;
1477 }
1478 
ToJson() const1479 std::unique_ptr<PtJson> CallArgument::ToJson() const
1480 {
1481     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1482 
1483     if (unserializableValue_) {
1484         result->Add("unserializableValue", unserializableValue_->c_str());
1485     }
1486     if (objectId_) {
1487         result->Add("objectId", std::to_string(objectId_.value()).c_str());
1488     }
1489 
1490     return result;
1491 }
1492 
Create(const PtJson & params)1493 std::unique_ptr<Location> Location::Create(const PtJson &params)
1494 {
1495     auto location = std::make_unique<Location>();
1496     std::string error;
1497     Result ret;
1498 
1499     std::string scriptId;
1500     ret = params.GetString("scriptId", &scriptId);
1501     if (ret == Result::SUCCESS) {
1502         location->scriptId_ = std::stoi(scriptId);
1503     } else {
1504         error += "Unknown 'scriptId';";
1505     }
1506     int32_t lineNumber;
1507     ret = params.GetInt("lineNumber", &lineNumber);
1508     if (ret == Result::SUCCESS) {
1509         location->lineNumber_ = lineNumber;
1510     } else {
1511         error += "Unknown 'lineNumber';";
1512     }
1513     int32_t columnNumber;
1514     ret = params.GetInt("columnNumber", &columnNumber);
1515     if (ret == Result::SUCCESS) {
1516         location->columnNumber_ = columnNumber;
1517     } else if (ret == Result::TYPE_ERROR) {  // optional value
1518         error += "Unknown 'columnNumber';";
1519     }
1520 
1521     if (!error.empty()) {
1522         LOG_DEBUGGER(ERROR) << "Location::Create " << error;
1523         return nullptr;
1524     }
1525 
1526     return location;
1527 }
1528 
ToJson() const1529 std::unique_ptr<PtJson> Location::ToJson() const
1530 {
1531     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1532 
1533     result->Add("scriptId", std::to_string(scriptId_).c_str());
1534     result->Add("lineNumber", lineNumber_);
1535     if (columnNumber_) {
1536         result->Add("columnNumber", columnNumber_.value());
1537     }
1538 
1539     return result;
1540 }
1541 
Create(const PtJson & params)1542 std::unique_ptr<ScriptPosition> ScriptPosition::Create(const PtJson &params)
1543 {
1544     auto scriptPosition = std::make_unique<ScriptPosition>();
1545     std::string error;
1546     Result ret;
1547 
1548     int32_t lineNumber;
1549     ret = params.GetInt("lineNumber", &lineNumber);
1550     if (ret == Result::SUCCESS) {
1551         scriptPosition->lineNumber_ = lineNumber;
1552     } else {
1553         error += "Unknown 'lineNumber';";
1554     }
1555     int32_t columnNumber;
1556     ret = params.GetInt("columnNumber", &columnNumber);
1557     if (ret == Result::SUCCESS) {
1558         scriptPosition->columnNumber_ = columnNumber;
1559     } else {
1560         error += "Unknown 'columnNumber';";
1561     }
1562 
1563     if (!error.empty()) {
1564         LOG_DEBUGGER(ERROR) << "ScriptPosition::Create " << error;
1565         return nullptr;
1566     }
1567 
1568     return scriptPosition;
1569 }
1570 
ToJson() const1571 std::unique_ptr<PtJson> ScriptPosition::ToJson() const
1572 {
1573     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1574 
1575     result->Add("lineNumber", lineNumber_);
1576     result->Add("columnNumber", columnNumber_);
1577 
1578     return result;
1579 }
1580 
Create(const PtJson & params)1581 std::unique_ptr<SearchMatch> SearchMatch::Create(const PtJson &params)
1582 {
1583     std::string error;
1584     auto locationSearch = std::make_unique<SearchMatch>();
1585     Result ret;
1586 
1587     int32_t lineNumber;
1588     ret = params.GetInt("lineNumber", &lineNumber);
1589     if (ret == Result::SUCCESS) {
1590         locationSearch->lineNumber_ = lineNumber;
1591     } else {
1592         error += "Unknown 'lineNumber';";
1593     }
1594 
1595     std::string lineContent;
1596     ret = params.GetString("lineContent", &lineContent);
1597     if (ret == Result::SUCCESS) {
1598         locationSearch->lineContent_ = std::move(lineContent);
1599     } else {
1600         error += "Unknown 'lineContent';";
1601     }
1602 
1603     if (!error.empty()) {
1604         LOG_DEBUGGER(ERROR) << "SearchMatch::Create " << error;
1605         return nullptr;
1606     }
1607 
1608     return locationSearch;
1609 }
1610 
ToJson() const1611 std::unique_ptr<PtJson> SearchMatch::ToJson() const
1612 {
1613     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1614 
1615     result->Add("lineNumber", lineNumber_);
1616     result->Add("lineContent", lineContent_.c_str());
1617 
1618     return result;
1619 }
1620 
Create(const PtJson & params)1621 std::unique_ptr<LocationRange> LocationRange::Create(const PtJson &params)
1622 {
1623     std::string error;
1624     auto locationRange = std::make_unique<LocationRange>();
1625     Result ret;
1626 
1627     std::string scriptId;
1628     ret = params.GetString("scriptId", &scriptId);
1629     if (ret == Result::SUCCESS) {
1630         locationRange->scriptId_ = std::stoi(scriptId);
1631     } else {
1632         error += "Unknown 'scriptId';";
1633     }
1634 
1635     std::unique_ptr<PtJson> start;
1636     std::unique_ptr<ScriptPosition> obj;
1637     ret = params.GetObject("start", &start);
1638     if (ret == Result::SUCCESS) {
1639         obj = ScriptPosition::Create(*start);
1640         if (obj == nullptr) {
1641             error += "'start' format error;";
1642         } else {
1643             locationRange->start_ = std::move(obj);
1644         }
1645     } else {
1646         error += "Unknown 'start';";
1647     }
1648 
1649     std::unique_ptr<PtJson> end;
1650     ret = params.GetObject("end", &end);
1651     if (ret == Result::SUCCESS) {
1652         obj = ScriptPosition::Create(*end);
1653         if (obj == nullptr) {
1654             error += "'end' format error;";
1655         } else {
1656             locationRange->end_ = std::move(obj);
1657         }
1658     } else {
1659         error += "Unknown 'end';";
1660     }
1661 
1662     if (!error.empty()) {
1663         LOG_DEBUGGER(ERROR) << "LocationRange::Create " << error;
1664         return nullptr;
1665     }
1666 
1667     return locationRange;
1668 }
1669 
ToJson() const1670 std::unique_ptr<PtJson> LocationRange::ToJson() const
1671 {
1672     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1673 
1674     result->Add("scriptId", std::to_string(scriptId_).c_str());
1675     ASSERT(start_ != nullptr);
1676     result->Add("start", start_->ToJson());
1677     ASSERT(end_ != nullptr);
1678     result->Add("end", end_->ToJson());
1679 
1680     return result;
1681 }
1682 
Create(const PtJson & params)1683 std::unique_ptr<BreakLocation> BreakLocation::Create(const PtJson &params)
1684 {
1685     std::string error;
1686     auto breakLocation = std::make_unique<BreakLocation>();
1687     Result ret;
1688 
1689     std::string scriptId;
1690     ret = params.GetString("scriptId", &scriptId);
1691     if (ret == Result::SUCCESS) {
1692         breakLocation->scriptId_ = std::stoi(scriptId);
1693     } else {
1694         error += "Unknown 'scriptId';";
1695     }
1696 
1697     int32_t lineNumber;
1698     ret = params.GetInt("lineNumber", &lineNumber);
1699     if (ret == Result::SUCCESS) {
1700         breakLocation->lineNumber_ = lineNumber;
1701     } else {
1702         error += "Unknown 'lineNumber';";
1703     }
1704 
1705     int32_t columnNumber;
1706     ret = params.GetInt("columnNumber", &columnNumber);
1707     if (ret == Result::SUCCESS) {
1708         breakLocation->columnNumber_ = columnNumber;
1709     } else if (ret == Result::TYPE_ERROR) {
1710         error += "Unknown 'columnNumber';";
1711     }
1712 
1713     std::string type;
1714     ret = params.GetString("type", &type);
1715     if (ret == Result::SUCCESS) {
1716         if (BreakType::Valid(type)) {
1717             breakLocation->type_ = std::move(type);
1718         } else {
1719             error += "'type' is invalid;";
1720         }
1721     } else if (ret == Result::TYPE_ERROR) {
1722         error += "type 'scriptId';";
1723     }
1724 
1725     if (!error.empty()) {
1726         LOG_DEBUGGER(ERROR) << "Location::Create " << error;
1727         return nullptr;
1728     }
1729 
1730     return breakLocation;
1731 }
1732 
ToJson() const1733 std::unique_ptr<PtJson> BreakLocation::ToJson() const
1734 {
1735     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1736 
1737     result->Add("scriptId", std::to_string(scriptId_).c_str());
1738     result->Add("lineNumber", lineNumber_);
1739     if (columnNumber_) {
1740         result->Add("columnNumber", columnNumber_.value());
1741     }
1742     if (type_) {
1743         result->Add("type", type_->c_str());
1744     }
1745 
1746     return result;
1747 }
1748 
Create(const PtJson & params)1749 std::unique_ptr<Scope> Scope::Create(const PtJson &params)
1750 {
1751     std::string error;
1752     auto scope = std::make_unique<Scope>();
1753     Result ret;
1754 
1755     std::string type;
1756     ret = params.GetString("type", &type);
1757     if (ret == Result::SUCCESS) {
1758         if (Scope::Type::Valid(type)) {
1759             scope->type_ = std::move(type);
1760         } else {
1761             error += "'type' is invalid;";
1762         }
1763     } else {
1764         error += "Unknown 'type';";
1765     }
1766 
1767     std::unique_ptr<PtJson> object;
1768     std::unique_ptr<RemoteObject> remoteObject;
1769     ret = params.GetObject("object", &object);
1770     if (ret == Result::SUCCESS) {
1771         remoteObject = RemoteObject::Create(*object);
1772         if (remoteObject == nullptr) {
1773             error += "'object' format error;";
1774         } else {
1775             scope->object_ = std::move(remoteObject);
1776         }
1777     } else {
1778         error += "Unknown 'object';";
1779     }
1780 
1781     std::string name;
1782     ret = params.GetString("name", &name);
1783     if (ret == Result::SUCCESS) {
1784         scope->name_ = std::move(name);
1785     } else if (ret == Result::TYPE_ERROR) {
1786         error += "Unknown 'name';";
1787     }
1788 
1789     std::unique_ptr<PtJson> startLocation;
1790     std::unique_ptr<Location> obj;
1791     ret = params.GetObject("startLocation", &startLocation);
1792     if (ret == Result::SUCCESS) {
1793         obj = Location::Create(*startLocation);
1794         if (obj == nullptr) {
1795             error += "'startLocation' format error;";
1796         } else {
1797             scope->startLocation_ = std::move(obj);
1798         }
1799     } else if (ret == Result::TYPE_ERROR) {
1800         error += "Unknown 'startLocation';";
1801     }
1802 
1803     std::unique_ptr<PtJson> endLocation;
1804     ret = params.GetObject("endLocation", &endLocation);
1805     if (ret == Result::SUCCESS) {
1806         obj = Location::Create(*endLocation);
1807         if (obj == nullptr) {
1808             error += "'endLocation' format error;";
1809         } else {
1810             scope->endLocation_ = std::move(obj);
1811         }
1812     } else if (ret == Result::TYPE_ERROR) {
1813         error += "Unknown 'endLocation';";
1814     }
1815 
1816     if (!error.empty()) {
1817         LOG_DEBUGGER(ERROR) << "Location::Create " << error;
1818         return nullptr;
1819     }
1820 
1821     return scope;
1822 }
1823 
ToJson() const1824 std::unique_ptr<PtJson> Scope::ToJson() const
1825 {
1826     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1827 
1828     result->Add("type", type_.c_str());
1829     ASSERT(object_ != nullptr);
1830     result->Add("object", object_->ToJson());
1831     if (name_) {
1832         result->Add("name", name_->c_str());
1833     }
1834     if (startLocation_) {
1835         ASSERT(startLocation_.value() != nullptr);
1836         result->Add("startLocation", startLocation_.value()->ToJson());
1837     }
1838     if (endLocation_) {
1839         ASSERT(endLocation_.value() != nullptr);
1840         result->Add("endLocation", endLocation_.value()->ToJson());
1841     }
1842 
1843     return result;
1844 }
1845 
Create(const PtJson & params)1846 std::unique_ptr<CallFrame> CallFrame::Create(const PtJson &params)
1847 {
1848     std::string error;
1849     auto callFrame = std::make_unique<CallFrame>();
1850     Result ret;
1851 
1852     std::string callFrameId;
1853     ret = params.GetString("callFrameId", &callFrameId);
1854     if (ret == Result::SUCCESS) {
1855         callFrame->callFrameId_ = std::stoi(callFrameId);
1856     } else {
1857         error += "Unknown 'callFrameId';";
1858     }
1859 
1860     std::string functionName;
1861     ret = params.GetString("functionName", &functionName);
1862     if (ret == Result::SUCCESS) {
1863         callFrame->functionName_ = std::move(functionName);
1864     } else {
1865         error += "Unknown 'functionName';";
1866     }
1867 
1868     std::unique_ptr<PtJson> functionLocation;
1869     std::unique_ptr<Location> obj;
1870     ret = params.GetObject("functionLocation", &functionLocation);
1871     if (ret == Result::SUCCESS) {
1872         obj = Location::Create(*functionLocation);
1873         if (obj == nullptr) {
1874             error += "'functionLocation' format error;";
1875         } else {
1876             callFrame->functionLocation_ = std::move(obj);
1877         }
1878     } else if (ret == Result::TYPE_ERROR) {
1879         error += "Unknown 'functionLocation';";
1880     }
1881 
1882     std::unique_ptr<PtJson> location;
1883     ret = params.GetObject("location", &location);
1884     if (ret == Result::SUCCESS) {
1885         obj = Location::Create(*location);
1886         if (obj == nullptr) {
1887             error += "'location' format error;";
1888         } else {
1889             callFrame->location_ = std::move(obj);
1890         }
1891     } else {
1892         error += "Unknown 'location';";
1893     }
1894 
1895     std::string url;
1896     ret = params.GetString("url", &url);
1897     if (ret == Result::SUCCESS) {
1898         callFrame->url_ = std::move(url);
1899     } else {
1900         error += "Unknown 'url';";
1901     }
1902 
1903     std::unique_ptr<PtJson> scopeChain;
1904     ret = params.GetArray("scopeChain", &scopeChain);
1905     if (ret == Result::SUCCESS) {
1906         int32_t len = scopeChain->GetSize();
1907         for (int32_t i = 0; i < len; ++i) {
1908             std::unique_ptr<PtJson> arrayEle = scopeChain->Get(i);
1909             ASSERT(arrayEle != nullptr);
1910             std::unique_ptr<Scope> scope = Scope::Create(*arrayEle);
1911             if (scope == nullptr) {
1912                 error += "'scopeChain' format error;";
1913             } else {
1914                 callFrame->scopeChain_.emplace_back(std::move(scope));
1915             }
1916         }
1917     } else {
1918         error += "Unknown 'scopeChain';";
1919     }
1920 
1921     std::unique_ptr<PtJson> thisObj;
1922     std::unique_ptr<RemoteObject> remoteObject;
1923     ret = params.GetObject("this", &thisObj);
1924     if (ret == Result::SUCCESS) {
1925         remoteObject = RemoteObject::Create(*thisObj);
1926         if (remoteObject == nullptr) {
1927             error += "'this' format error;";
1928         } else {
1929             callFrame->this_ = std::move(remoteObject);
1930         }
1931     } else {
1932         error += "Unknown 'this';";
1933     }
1934 
1935     std::unique_ptr<PtJson> returnValue;
1936     ret = params.GetObject("returnValue", &returnValue);
1937     if (ret == Result::SUCCESS) {
1938         remoteObject = RemoteObject::Create(*returnValue);
1939         if (remoteObject == nullptr) {
1940             error += "'returnValue' format error;";
1941         } else {
1942             callFrame->returnValue_ = std::move(remoteObject);
1943         }
1944     } else if (ret == Result::TYPE_ERROR) {
1945         error += "Unknown 'returnValue';";
1946     }
1947 
1948     if (!error.empty()) {
1949         LOG_DEBUGGER(ERROR) << "CallFrame::Create " << error;
1950         return nullptr;
1951     }
1952 
1953     return callFrame;
1954 }
1955 
ToJson() const1956 std::unique_ptr<PtJson> CallFrame::ToJson() const
1957 {
1958     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1959 
1960     result->Add("callFrameId", std::to_string(callFrameId_).c_str());
1961     result->Add("functionName", functionName_.c_str());
1962 
1963     if (functionLocation_) {
1964         ASSERT(functionLocation_.value() != nullptr);
1965         result->Add("functionLocation", functionLocation_.value()->ToJson());
1966     }
1967     ASSERT(location_ != nullptr);
1968     result->Add("location", location_->ToJson());
1969     result->Add("url", url_.c_str());
1970 
1971     size_t len = scopeChain_.size();
1972     std::unique_ptr<PtJson> values = PtJson::CreateArray();
1973     for (size_t i = 0; i < len; i++) {
1974         ASSERT(scopeChain_[i] != nullptr);
1975         std::unique_ptr<PtJson> scope = scopeChain_[i]->ToJson();
1976         values->Push(scope);
1977     }
1978     result->Add("scopeChain", values);
1979 
1980     ASSERT(this_ != nullptr);
1981     result->Add("this", this_->ToJson());
1982     if (returnValue_) {
1983         ASSERT(returnValue_.value() != nullptr);
1984         result->Add("returnValue", returnValue_.value()->ToJson());
1985     }
1986 
1987     return result;
1988 }
1989 
Create(const PtJson & params)1990 std::unique_ptr<SamplingHeapProfileSample> SamplingHeapProfileSample::Create(const PtJson &params)
1991 {
1992     std::string error;
1993     auto samplingHeapProfileSample = std::make_unique<SamplingHeapProfileSample>();
1994     Result ret;
1995 
1996     int32_t size;
1997     ret = params.GetInt("size", &size);
1998     if (ret == Result::SUCCESS) {
1999         samplingHeapProfileSample->size_ = size;
2000     } else {
2001         error += "Unknown 'size';";
2002     }
2003     int32_t nodeId;
2004     ret = params.GetInt("nodeId", &nodeId);
2005     if (ret == Result::SUCCESS) {
2006         samplingHeapProfileSample->nodeId_ = nodeId;
2007     } else {
2008         error += "Unknown 'nodeId';";
2009     }
2010     int32_t ordinal;
2011     ret = params.GetInt("ordinal", &ordinal);
2012     if (ret == Result::SUCCESS) {
2013         samplingHeapProfileSample->ordinal_ = ordinal;
2014     } else {
2015         error += "Unknown 'ordinal';";
2016     }
2017     if (!error.empty()) {
2018         LOG_DEBUGGER(ERROR) << "SamplingHeapProfileSample::Create " << error;
2019         return nullptr;
2020     }
2021 
2022     return samplingHeapProfileSample;
2023 }
2024 
ToJson() const2025 std::unique_ptr<PtJson> SamplingHeapProfileSample::ToJson() const
2026 {
2027     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2028 
2029     result->Add("size", size_);
2030     result->Add("nodeId", nodeId_);
2031     result->Add("ordinal", ordinal_);
2032 
2033     return result;
2034 }
2035 
Create(const PtJson & params)2036 std::unique_ptr<RuntimeCallFrame> RuntimeCallFrame::Create(const PtJson &params)
2037 {
2038     std::string error;
2039     auto runtimeCallFrame = std::make_unique<RuntimeCallFrame>();
2040     Result ret;
2041 
2042     std::string functionName;
2043     ret = params.GetString("functionName", &functionName);
2044     if (ret == Result::SUCCESS) {
2045         runtimeCallFrame->functionName_ = std::move(functionName);
2046     } else {
2047         error += "Unknown 'functionName';";
2048     }
2049 
2050     std::string moduleName;
2051     ret = params.GetString("moduleName", &moduleName);
2052     if (ret == Result::SUCCESS) {
2053         runtimeCallFrame->moduleName_ = std::move(moduleName);
2054     } else {
2055         error += "Unknown 'moduleName';";
2056     }
2057 
2058     std::string scriptId;
2059     ret = params.GetString("scriptId", &scriptId);
2060     if (ret == Result::SUCCESS) {
2061         runtimeCallFrame->scriptId_ = std::move(scriptId);
2062     } else {
2063         error += "Unknown 'scriptId';";
2064     }
2065 
2066     std::string url;
2067     ret = params.GetString("url", &url);
2068     if (ret == Result::SUCCESS) {
2069         runtimeCallFrame->url_ = std::move(url);
2070     } else {
2071         error += "Unknown 'url';";
2072     }
2073 
2074     int32_t lineNumber;
2075     ret = params.GetInt("lineNumber", &lineNumber);
2076     if (ret == Result::SUCCESS) {
2077         runtimeCallFrame->lineNumber_ = lineNumber;
2078     } else {
2079         error += "Unknown 'lineNumber';";
2080     }
2081 
2082     int32_t columnNumber;
2083     ret = params.GetInt("columnNumber", &columnNumber);
2084     if (ret == Result::SUCCESS) {
2085         runtimeCallFrame->columnNumber_ = columnNumber;
2086     } else {
2087         error += "Unknown 'columnNumber';";
2088     }
2089     if (!error.empty()) {
2090         LOG_DEBUGGER(ERROR) << "RuntimeCallFrame::Create " << error;
2091         return nullptr;
2092     }
2093 
2094     return runtimeCallFrame;
2095 }
2096 
FromFrameInfo(const FrameInfo & cpuFrameInfo)2097 std::unique_ptr<RuntimeCallFrame> RuntimeCallFrame::FromFrameInfo(const FrameInfo &cpuFrameInfo)
2098 {
2099     auto runtimeCallFrame = std::make_unique<RuntimeCallFrame>();
2100     runtimeCallFrame->SetFunctionName(cpuFrameInfo.functionName);
2101     runtimeCallFrame->SetModuleName(cpuFrameInfo.moduleName);
2102     runtimeCallFrame->SetScriptId(std::to_string(cpuFrameInfo.scriptId));
2103     runtimeCallFrame->SetColumnNumber(cpuFrameInfo.columnNumber);
2104     runtimeCallFrame->SetLineNumber(cpuFrameInfo.lineNumber);
2105     runtimeCallFrame->SetUrl(cpuFrameInfo.url);
2106     return runtimeCallFrame;
2107 }
2108 
ToJson() const2109 std::unique_ptr<PtJson> RuntimeCallFrame::ToJson() const
2110 {
2111     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2112 
2113     result->Add("functionName", functionName_.c_str());
2114     result->Add("moduleName", moduleName_.c_str());
2115     result->Add("scriptId", scriptId_.c_str());
2116     result->Add("url", url_.c_str());
2117     result->Add("lineNumber", lineNumber_);
2118     result->Add("columnNumber", columnNumber_);
2119 
2120     return result;
2121 }
2122 
Create(const PtJson & params)2123 std::unique_ptr<SamplingHeapProfileNode> SamplingHeapProfileNode::Create(const PtJson &params)
2124 {
2125     std::string error;
2126     auto samplingHeapProfileNode = std::make_unique<SamplingHeapProfileNode>();
2127     Result ret;
2128 
2129     std::unique_ptr<PtJson> callFrame;
2130     ret = params.GetObject("callFrame", &callFrame);
2131     if (ret == Result::SUCCESS) {
2132         std::unique_ptr<RuntimeCallFrame> runtimeCallFrame = RuntimeCallFrame::Create(*callFrame);
2133         if (runtimeCallFrame == nullptr) {
2134             error += "'callFrame' format invalid;";
2135         } else {
2136             samplingHeapProfileNode->callFrame_ = std::move(runtimeCallFrame);
2137         }
2138     } else {
2139         error += "Unknown 'callFrame';";
2140     }
2141 
2142     int32_t selfSize;
2143     ret = params.GetInt("selfSize", &selfSize);
2144     if (ret == Result::SUCCESS) {
2145         samplingHeapProfileNode->selfSize_ = selfSize;
2146     } else {
2147         error += "Unknown 'selfSize';";
2148     }
2149 
2150     int32_t id;
2151     ret = params.GetInt("id", &id);
2152     if (ret == Result::SUCCESS) {
2153         samplingHeapProfileNode->id_ = id;
2154     } else {
2155         error += "Unknown 'id';";
2156     }
2157 
2158     std::unique_ptr<PtJson> children;
2159     ret = params.GetArray("children", &children);
2160     if (ret == Result::SUCCESS) {
2161         int32_t len = children->GetSize();
2162         for (int32_t i = 0; i < len; ++i) {
2163             std::unique_ptr<PtJson> arrayEle = children->Get(i);
2164             ASSERT(arrayEle != nullptr);
2165             std::unique_ptr<SamplingHeapProfileNode> node = SamplingHeapProfileNode::Create(*arrayEle);
2166             if (node == nullptr) {
2167                 error += "'children' format invalid;";
2168             } else {
2169                 samplingHeapProfileNode->children_.emplace_back(std::move(node));
2170             }
2171         }
2172     } else {
2173         error += "Unknown 'children';";
2174     }
2175 
2176     if (!error.empty()) {
2177         LOG_DEBUGGER(ERROR) << "SamplingHeapProfileNode::Create " << error;
2178         return nullptr;
2179     }
2180 
2181     return samplingHeapProfileNode;
2182 }
2183 
ToJson() const2184 std::unique_ptr<PtJson> SamplingHeapProfileNode::ToJson() const
2185 {
2186     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2187     ASSERT(callFrame_ != nullptr);
2188     result->Add("callFrame", callFrame_->ToJson());
2189     result->Add("selfSize", selfSize_);
2190     result->Add("id", id_);
2191 
2192     std::unique_ptr<PtJson> childrens = PtJson::CreateArray();
2193     size_t len = children_.size();
2194     for (size_t i = 0; i < len; i++) {
2195         ASSERT(children_[i] != nullptr);
2196         childrens->Push(children_[i]->ToJson());
2197     }
2198     result->Add("children", childrens);
2199 
2200     return result;
2201 }
2202 
Create(const PtJson & params)2203 std::unique_ptr<SamplingHeapProfile> SamplingHeapProfile::Create(const PtJson &params)
2204 {
2205     std::string error;
2206     auto samplingHeapProfile = std::make_unique<SamplingHeapProfile>();
2207     Result ret;
2208 
2209     std::unique_ptr<PtJson> head;
2210     ret = params.GetObject("head", &head);
2211     if (ret == Result::SUCCESS) {
2212         std::unique_ptr<SamplingHeapProfileNode> pHead = SamplingHeapProfileNode::Create(*head);
2213         if (pHead == nullptr) {
2214             error += "'sample' format invalid;";
2215         } else {
2216             samplingHeapProfile->head_ = std::move(pHead);
2217         }
2218     } else {
2219         error += "Unknown 'head';";
2220     }
2221 
2222     std::unique_ptr<PtJson> samples;
2223     ret = params.GetArray("samples", &samples);
2224     if (ret == Result::SUCCESS) {
2225         int32_t len = samples->GetSize();
2226         for (int32_t i = 0; i < len; ++i) {
2227             std::unique_ptr<PtJson> arrayEle = samples->Get(i);
2228             ASSERT(arrayEle != nullptr);
2229             std::unique_ptr<SamplingHeapProfileSample> pSample = SamplingHeapProfileSample::Create(*arrayEle);
2230             if (pSample == nullptr) {
2231                 error += "'sample' format invalid;";
2232             } else {
2233                 samplingHeapProfile->samples_.emplace_back(std::move(pSample));
2234             }
2235         }
2236     } else {
2237         error += "Unknown 'samples';";
2238     }
2239 
2240     if (!error.empty()) {
2241         LOG_DEBUGGER(ERROR) << "SamplingHeapProfile::Create " << error;
2242         return nullptr;
2243     }
2244 
2245     return samplingHeapProfile;
2246 }
2247 
ToJson() const2248 std::unique_ptr<PtJson> SamplingHeapProfile::ToJson() const
2249 {
2250     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2251 
2252     ASSERT(head_ != nullptr);
2253     result->Add("head", head_->ToJson());
2254 
2255     std::unique_ptr<PtJson> samples = PtJson::CreateArray();
2256     size_t len = samples_.size();
2257     for (size_t i = 0; i < len; i++) {
2258         ASSERT(samples_[i] != nullptr);
2259         samples->Push(samples_[i]->ToJson());
2260     }
2261     result->Add("samples", samples);
2262     return result;
2263 }
2264 
FromSamplingInfo(const SamplingInfo * samplingInfo)2265 std::unique_ptr<SamplingHeapProfile> SamplingHeapProfile::FromSamplingInfo(
2266     const SamplingInfo *samplingInfo)
2267 {
2268     std::unique_ptr<SamplingHeapProfile> profile = std::make_unique<SamplingHeapProfile>();
2269     auto node = TransferHead(&(samplingInfo->head_));
2270     profile->head_ = std::move(node);
2271     const CVector<struct Sample> &samples = samplingInfo->samples_;
2272     for (const auto &sample : samples) {
2273         std::unique_ptr<SamplingHeapProfileSample> sampleTemp = std::make_unique<SamplingHeapProfileSample>();
2274         sampleTemp->SetSize(sample.size_ * sample.count_);
2275         sampleTemp->SetNodeId(sample.nodeId_);
2276         sampleTemp->SetOrdinal(sample.ordinal_);
2277         profile->samples_.emplace_back(std::move(sampleTemp));
2278     }
2279     return profile;
2280 }
2281 
TransferHead(const SamplingNode * samplingNode)2282 std::unique_ptr<SamplingHeapProfileNode> SamplingHeapProfile::TransferHead(const SamplingNode *samplingNode)
2283 {
2284     std::unique_ptr<SamplingHeapProfileNode> node = std::make_unique<SamplingHeapProfileNode>();
2285     node->SetSelfSize(samplingNode->selfSize_);
2286     node->SetId(samplingNode->id_);
2287     std::unique_ptr<RuntimeCallFrame> callFrame = std::make_unique<RuntimeCallFrame>();
2288     callFrame->SetFunctionName(samplingNode->callFrameInfo_.functionName_);
2289     callFrame->SetScriptId(std::to_string(samplingNode->callFrameInfo_.scriptId_));
2290     callFrame->SetUrl(samplingNode->callFrameInfo_.url_);
2291     callFrame->SetLineNumber(samplingNode->callFrameInfo_.lineNumber_);
2292     callFrame->SetColumnNumber(samplingNode->callFrameInfo_.columnNumber_);
2293     node->SetCallFrame(std::move(callFrame));
2294     std::vector<std::unique_ptr<SamplingHeapProfileNode>> profileNode;
2295     for (const auto &it : samplingNode->children_) {
2296         auto proNode = TransferHead(it.second.get());
2297         profileNode.push_back(std::move(proNode));
2298     }
2299     node->SetChildren(std::move(profileNode));
2300     return node;
2301 }
2302 
Create(const PtJson & params)2303 std::unique_ptr<PositionTickInfo> PositionTickInfo::Create(const PtJson &params)
2304 {
2305     std::string error;
2306     auto positionTickInfo = std::make_unique<PositionTickInfo>();
2307     Result ret;
2308 
2309     int32_t line;
2310     ret = params.GetInt("line", &line);
2311     if (ret == Result::SUCCESS) {
2312         positionTickInfo->line_ = line;
2313     } else {
2314         error += "Unknown 'line';";
2315     }
2316 
2317     int32_t ticks;
2318     ret = params.GetInt("ticks", &ticks);
2319     if (ret == Result::SUCCESS) {
2320         positionTickInfo->ticks_ = ticks;
2321     } else {
2322         error += "Unknown 'ticks';";
2323     }
2324 
2325     if (!error.empty()) {
2326         LOG_DEBUGGER(ERROR) << "PositionTickInfo::Create " << error;
2327         return nullptr;
2328     }
2329 
2330     return positionTickInfo;
2331 }
2332 
ToJson() const2333 std::unique_ptr<PtJson> PositionTickInfo::ToJson() const
2334 {
2335     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2336 
2337     result->Add("line", line_);
2338     result->Add("ticks", ticks_);
2339 
2340     return result;
2341 }
2342 
Create(const PtJson & params)2343 std::unique_ptr<ProfileNode> ProfileNode::Create(const PtJson &params)
2344 {
2345     std::string error;
2346     auto profileNode = std::make_unique<ProfileNode>();
2347     Result ret;
2348 
2349     int32_t id;
2350     ret = params.GetInt("id", &id);
2351     if (ret == Result::SUCCESS) {
2352         profileNode->id_ = id;
2353     } else {
2354         error += "Unknown 'id';";
2355     }
2356 
2357     std::unique_ptr<PtJson> callFrame;
2358     ret = params.GetObject("callFrame", &callFrame);
2359     if (ret == Result::SUCCESS) {
2360         std::unique_ptr<RuntimeCallFrame> runtimeCallFrame = RuntimeCallFrame::Create(*callFrame);
2361         if (runtimeCallFrame == nullptr) {
2362             error += "'callFrame' format invalid;";
2363         } else {
2364             profileNode->callFrame_ = std::move(runtimeCallFrame);
2365         }
2366     } else {
2367         error += "Unknown 'callFrame';";
2368     }
2369 
2370     int32_t hitCount;
2371     ret = params.GetInt("hitCount", &hitCount);
2372     if (ret == Result::SUCCESS) {
2373         profileNode->hitCount_ = hitCount;
2374     } else if (ret == Result::TYPE_ERROR) {
2375         error += "Unknown 'hitCount';";
2376     }
2377 
2378     std::unique_ptr<PtJson> children;
2379     ret = params.GetArray("children", &children);
2380     if (ret == Result::SUCCESS) {
2381         int32_t childrenLen = children->GetSize();
2382         for (int32_t i = 0; i < childrenLen; ++i) {
2383             int32_t pChildren = children->Get(i)->GetInt();
2384             profileNode->children_.value().emplace_back(pChildren);
2385         }
2386     }  else if (ret == Result::TYPE_ERROR) {
2387         error += "Unknown 'children';";
2388     }
2389 
2390     std::unique_ptr<PtJson> positionTicks;
2391     ret = params.GetArray("positionTicks", &positionTicks);
2392     if (ret == Result::SUCCESS) {
2393         int32_t positionTicksLen = positionTicks->GetSize();
2394         for (int32_t i = 0; i < positionTicksLen; ++i) {
2395             std::unique_ptr<PtJson> arrayEle = positionTicks->Get(i);
2396             ASSERT(arrayEle != nullptr);
2397             std::unique_ptr<PositionTickInfo> tmpPositionTicks = PositionTickInfo::Create(*arrayEle);
2398             if (tmpPositionTicks == nullptr) {
2399                 error += "'positionTicks' format invalid;";
2400             } else {
2401                 profileNode->positionTicks_.value().emplace_back(std::move(tmpPositionTicks));
2402             }
2403         }
2404     } else if (ret == Result::TYPE_ERROR) {
2405         error += "Unknown 'positionTicks';";
2406     }
2407 
2408     std::string deoptReason;
2409     ret = params.GetString("deoptReason", &deoptReason);
2410     if (ret == Result::SUCCESS) {
2411         profileNode->deoptReason_ = std::move(deoptReason);
2412     } else if (ret == Result::TYPE_ERROR) {
2413         error += "Unknown 'deoptReason';";
2414     }
2415 
2416     if (!error.empty()) {
2417         LOG_DEBUGGER(ERROR) << "ProfileNode::Create " << error;
2418         return nullptr;
2419     }
2420 
2421     return profileNode;
2422 }
2423 
FromCpuProfileNode(const CpuProfileNode & cpuProfileNode)2424 std::unique_ptr<ProfileNode> ProfileNode::FromCpuProfileNode(const CpuProfileNode &cpuProfileNode)
2425 {
2426     auto profileNode = std::make_unique<ProfileNode>();
2427     profileNode->SetId(cpuProfileNode.id);
2428     profileNode->SetHitCount(cpuProfileNode.hitCount);
2429 
2430     size_t childrenLen = cpuProfileNode.children.size();
2431     std::vector<int32_t> tmpChildren;
2432     tmpChildren.reserve(childrenLen);
2433     for (size_t i = 0; i < childrenLen; ++i) {
2434         tmpChildren.push_back(cpuProfileNode.children[i]);
2435     }
2436     profileNode->SetChildren(tmpChildren);
2437     profileNode->SetCallFrame(RuntimeCallFrame::FromFrameInfo(cpuProfileNode.codeEntry));
2438     return profileNode;
2439 }
2440 
ToJson() const2441 std::unique_ptr<PtJson> ProfileNode::ToJson() const
2442 {
2443     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2444 
2445     result->Add("id", id_);
2446     ASSERT(callFrame_ != nullptr);
2447     result->Add("callFrame", callFrame_->ToJson());
2448     if (hitCount_) {
2449         result->Add("hitCount", hitCount_.value());
2450     }
2451     if (children_) {
2452         std::unique_ptr<PtJson> childrens = PtJson::CreateArray();
2453         size_t len = children_->size();
2454         for (size_t i = 0; i < len; i++) {
2455             childrens->Push(children_.value()[i]);
2456         }
2457         result->Add("children", childrens);
2458     }
2459     if (positionTicks_) {
2460         std::unique_ptr<PtJson> positionTicks = PtJson::CreateArray();
2461         size_t len = positionTicks_->size();
2462         for (size_t i = 0; i < len; i++) {
2463             ASSERT(positionTicks_.value()[i] != nullptr);
2464             positionTicks->Push(positionTicks_.value()[i]->ToJson());
2465         }
2466         result->Add("positionTicks", positionTicks);
2467     }
2468 
2469     if (deoptReason_) {
2470         result->Add("deoptReason", deoptReason_.value().c_str());
2471     }
2472 
2473     return result;
2474 }
2475 
Create(const PtJson & params)2476 std::unique_ptr<Profile> Profile::Create(const PtJson &params)
2477 {
2478     std::string error;
2479     auto profile = std::make_unique<Profile>();
2480     Result ret;
2481 
2482     std::unique_ptr<PtJson> nodes;
2483     ret = params.GetArray("nodes", &nodes);
2484     if (ret == Result::SUCCESS) {
2485         int32_t nodesLen = nodes->GetSize();
2486         for (int32_t i = 0; i < nodesLen; ++i) {
2487             std::unique_ptr<PtJson> arrayEle = nodes->Get(i);
2488             ASSERT(arrayEle != nullptr);
2489             std::unique_ptr<ProfileNode> profileNode = ProfileNode::Create(*arrayEle);
2490             if (profileNode == nullptr) {
2491                 error += "'nodes' format invalid;";
2492             } else {
2493                 profile->nodes_.emplace_back(std::move(profileNode));
2494             }
2495         }
2496     } else {
2497         error += "Unknown 'nodes';";
2498     }
2499 
2500     int64_t tid;
2501     ret = params.GetInt64("tid", &tid);
2502     if (ret == Result::SUCCESS) {
2503         profile->tid_ = tid;
2504     } else {
2505         error += "Unknown 'tid';";
2506     }
2507 
2508     int64_t startTime;
2509     ret = params.GetInt64("startTime", &startTime);
2510     if (ret == Result::SUCCESS) {
2511         profile->startTime_ = startTime;
2512     } else {
2513         error += "Unknown 'startTime';";
2514     }
2515 
2516     int64_t endTime;
2517     ret = params.GetInt64("endTime", &endTime);
2518     if (ret == Result::SUCCESS) {
2519         profile->endTime_ = endTime;
2520     } else {
2521         error += "Unknown 'endTime';";
2522     }
2523 
2524     int64_t gcTime;
2525     ret = params.GetInt64("gcTime", &gcTime);
2526     if (ret == Result::SUCCESS) {
2527         profile->gcTime_ = gcTime;
2528     } else {
2529         error += "Unknown 'gcTime';";
2530     }
2531 
2532     int64_t cInterpreterTime;
2533     ret = params.GetInt64("cInterpreterTime", &cInterpreterTime);
2534     if (ret == Result::SUCCESS) {
2535         profile->cInterpreterTime_ = cInterpreterTime;
2536     } else {
2537         error += "Unknown 'cInterpreterTime';";
2538     }
2539 
2540     int64_t asmInterpreterTime;
2541     ret = params.GetInt64("asmInterpreterTime", &asmInterpreterTime);
2542     if (ret == Result::SUCCESS) {
2543         profile->asmInterpreterTime_ = asmInterpreterTime;
2544     } else {
2545         error += "Unknown 'asmInterpreterTime';";
2546     }
2547 
2548     int64_t aotTime;
2549     ret = params.GetInt64("aotTime", &aotTime);
2550     if (ret == Result::SUCCESS) {
2551         profile->aotTime_ = aotTime;
2552     } else {
2553         error += "Unknown 'aotTime';";
2554     }
2555 
2556     int64_t builtinTime;
2557     ret = params.GetInt64("builtinTime", &builtinTime);
2558     if (ret == Result::SUCCESS) {
2559         profile->builtinTime_ = builtinTime;
2560     } else {
2561         error += "Unknown 'builtinTime';";
2562     }
2563 
2564     int64_t napiTime;
2565     ret = params.GetInt64("napiTime", &napiTime);
2566     if (ret == Result::SUCCESS) {
2567         profile->napiTime_ = napiTime;
2568     } else {
2569         error += "Unknown 'napiTime';";
2570     }
2571 
2572     int64_t arkuiEngineTime;
2573     ret = params.GetInt64("arkuiEngineTime", &arkuiEngineTime);
2574     if (ret == Result::SUCCESS) {
2575         profile->arkuiEngineTime_ = arkuiEngineTime;
2576     } else {
2577         error += "Unknown 'arkuiEngineTime';";
2578     }
2579 
2580     int64_t runtimeTime;
2581     ret = params.GetInt64("runtimeTime", &runtimeTime);
2582     if (ret == Result::SUCCESS) {
2583         profile->runtimeTime_ = runtimeTime;
2584     } else {
2585         error += "Unknown 'runtimeTime';";
2586     }
2587 
2588     int64_t otherTime;
2589     ret = params.GetInt64("otherTime", &otherTime);
2590     if (ret == Result::SUCCESS) {
2591         profile->otherTime_ = otherTime;
2592     } else {
2593         error += "Unknown 'otherTime';";
2594     }
2595 
2596     std::unique_ptr<PtJson> samples;
2597     ret = params.GetArray("samples", &samples);
2598     if (ret == Result::SUCCESS) {
2599         int32_t samplesLen = samples->GetSize();
2600         for (int32_t i = 0; i < samplesLen; ++i) {
2601             int32_t pSamples = samples->Get(i)->GetInt();
2602             profile->samples_.value().emplace_back(pSamples);
2603         }
2604     }  else if (ret == Result::TYPE_ERROR) {
2605         error += "Unknown 'samples';";
2606     }
2607 
2608     std::unique_ptr<PtJson> timeDeltas;
2609     ret = params.GetArray("timeDeltas", &timeDeltas);
2610     if (ret == Result::SUCCESS) {
2611         int32_t timeDeltasLen = timeDeltas->GetSize();
2612         for (int32_t i = 0; i < timeDeltasLen; ++i) {
2613             int32_t pTimeDeltas = timeDeltas->Get(i)->GetInt();
2614             profile->timeDeltas_.value().emplace_back(pTimeDeltas);
2615         }
2616     }  else if (ret == Result::TYPE_ERROR) {
2617         error += "Unknown 'timeDeltas';";
2618     }
2619 
2620     if (!error.empty()) {
2621         LOG_DEBUGGER(ERROR) << "Profile::Create " << error;
2622         return nullptr;
2623     }
2624 
2625     return profile;
2626 }
2627 
FromProfileInfo(const ProfileInfo & profileInfo)2628 std::unique_ptr<Profile> Profile::FromProfileInfo(const ProfileInfo &profileInfo)
2629 {
2630     auto profile = std::make_unique<Profile>();
2631     profile->SetTid(static_cast<int64_t>(profileInfo.tid));
2632     profile->SetStartTime(static_cast<int64_t>(profileInfo.startTime));
2633     profile->SetEndTime(static_cast<int64_t>(profileInfo.stopTime));
2634     profile->SetGcTime(static_cast<int64_t>(profileInfo.gcTime));
2635     profile->SetCInterpreterTime(static_cast<int64_t>(profileInfo.cInterpreterTime));
2636     profile->SetAsmInterpreterTime(static_cast<int64_t>(profileInfo.asmInterpreterTime));
2637     profile->SetAotTime(static_cast<int64_t>(profileInfo.aotTime));
2638     profile->SetBuiltinTime(static_cast<int64_t>(profileInfo.builtinTime));
2639     profile->SetNapiTime(static_cast<int64_t>(profileInfo.napiTime));
2640     profile->SetArkuiEngineTime(static_cast<int64_t>(profileInfo.arkuiEngineTime));
2641     profile->SetRuntimeTime(static_cast<int64_t>(profileInfo.runtimeTime));
2642     profile->SetOtherTime(static_cast<int64_t>(profileInfo.otherTime));
2643     size_t samplesLen = profileInfo.samples.size();
2644     std::vector<int32_t> tmpSamples;
2645     tmpSamples.reserve(samplesLen);
2646     for (size_t i = 0; i < samplesLen; ++i) {
2647         tmpSamples.push_back(profileInfo.samples[i]);
2648     }
2649     profile->SetSamples(tmpSamples);
2650 
2651     size_t timeDeltasLen = profileInfo.timeDeltas.size();
2652     std::vector<int32_t> tmpTimeDeltas;
2653     tmpTimeDeltas.reserve(timeDeltasLen);
2654     for (size_t i = 0; i < timeDeltasLen; ++i) {
2655         tmpTimeDeltas.push_back(profileInfo.timeDeltas[i]);
2656     }
2657     profile->SetTimeDeltas(tmpTimeDeltas);
2658 
2659     std::vector<std::unique_ptr<ProfileNode>> profileNode;
2660     size_t nodesLen = profileInfo.nodeCount;
2661     for (size_t i = 0; i < nodesLen; ++i) {
2662         const auto &cpuProfileNode = profileInfo.nodes[i];
2663         profileNode.push_back(ProfileNode::FromCpuProfileNode(cpuProfileNode));
2664     }
2665     profile->SetNodes(std::move(profileNode));
2666     return profile;
2667 }
2668 
ToJson() const2669 std::unique_ptr<PtJson> Profile::ToJson() const
2670 {
2671     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2672 
2673     result->Add("tid", tid_);
2674     result->Add("startTime", startTime_);
2675     result->Add("endTime", endTime_);
2676     result->Add("gcTime", gcTime_);
2677     result->Add("cInterpreterTime", cInterpreterTime_);
2678     result->Add("asmInterpreterTime", asmInterpreterTime_);
2679     result->Add("aotTime", aotTime_);
2680     result->Add("builtinTime", builtinTime_);
2681     result->Add("napiTime", napiTime_);
2682     result->Add("arkuiEngineTime", arkuiEngineTime_);
2683     result->Add("runtimeTime", runtimeTime_);
2684     result->Add("otherTime", otherTime_);
2685 
2686     std::unique_ptr<PtJson> nodes = PtJson::CreateArray();
2687     size_t nodesLen = nodes_.size();
2688     for (size_t i = 0; i < nodesLen; i++) {
2689         ASSERT(nodes_[i] != nullptr);
2690         nodes->Push(nodes_[i]->ToJson());
2691     }
2692     result->Add("nodes", nodes);
2693 
2694     if (samples_) {
2695         std::unique_ptr<PtJson> samples = PtJson::CreateArray();
2696         size_t samplesLen = samples_->size();
2697         for (size_t i = 0; i < samplesLen; i++) {
2698             samples->Push(samples_.value()[i]);
2699         }
2700         result->Add("samples", samples);
2701     }
2702 
2703     if (timeDeltas_) {
2704         std::unique_ptr<PtJson> timeDeltas = PtJson::CreateArray();
2705         size_t timeDeltasLen = timeDeltas_->size();
2706         for (size_t i = 0; i < timeDeltasLen; i++) {
2707             timeDeltas->Push(timeDeltas_.value()[i]);
2708         }
2709         result->Add("timeDeltas", timeDeltas);
2710     }
2711 
2712     return result;
2713 }
2714 
Create(const PtJson & params)2715 std::unique_ptr<Coverage> Coverage::Create(const PtJson &params)
2716 {
2717     std::string error;
2718     auto coverage = std::make_unique<Coverage>();
2719     Result ret;
2720 
2721     int32_t startOffset;
2722     ret = params.GetInt("startOffset", &startOffset);
2723     if (ret == Result::SUCCESS) {
2724         coverage->startOffset_ = startOffset;
2725     } else {
2726         error += "Unknown 'startOffset';";
2727     }
2728 
2729     int32_t endOffset;
2730     ret = params.GetInt("endOffset", &endOffset);
2731     if (ret == Result::SUCCESS) {
2732         coverage->endOffset_ = endOffset;
2733     } else {
2734         error += "Unknown 'endOffset';";
2735     }
2736 
2737     int32_t count;
2738     ret = params.GetInt("count", &count);
2739     if (ret == Result::SUCCESS) {
2740         coverage->count_ = count;
2741     } else {
2742         error += "Unknown 'count';";
2743     }
2744 
2745     if (!error.empty()) {
2746         LOG_DEBUGGER(ERROR) << "Coverage::Create " << error;
2747         return nullptr;
2748     }
2749 
2750     return coverage;
2751 }
2752 
ToJson() const2753 std::unique_ptr<PtJson> Coverage::ToJson() const
2754 {
2755     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2756 
2757     result->Add("startOffset", startOffset_);
2758     result->Add("endOffset", endOffset_);
2759     result->Add("count", count_);
2760 
2761     return result;
2762 }
2763 
Create(const PtJson & params)2764 std::unique_ptr<FunctionCoverage> FunctionCoverage::Create(const PtJson &params)
2765 {
2766     std::string error;
2767     auto functionCoverage = std::make_unique<FunctionCoverage>();
2768     Result ret;
2769 
2770     std::string functionName;
2771     ret = params.GetString("functionName", &functionName);
2772     if (ret == Result::SUCCESS) {
2773         functionCoverage->functionName_ = std::move(functionName);
2774     } else {
2775         error += "Unknown 'functionName';";
2776     }
2777 
2778     std::unique_ptr<PtJson> ranges;
2779     ret = params.GetArray("ranges", &ranges);
2780     if (ret == Result::SUCCESS) {
2781         int32_t len = ranges->GetSize();
2782         for (int32_t i = 0; i < len; ++i) {
2783             std::unique_ptr<PtJson> arrayEle = ranges->Get(i);
2784             ASSERT(arrayEle != nullptr);
2785             std::unique_ptr<Coverage> pRanges = Coverage::Create(*arrayEle);
2786             if (pRanges == nullptr) {
2787                 error += "'ranges' format invalid;";
2788             } else {
2789                 functionCoverage->ranges_.emplace_back(std::move(pRanges));
2790             }
2791         }
2792     } else {
2793         error += "Unknown 'ranges';";
2794     }
2795 
2796     bool isBlockCoverage = false;
2797     ret = params.GetBool("isBlockCoverage", &isBlockCoverage);
2798     if (ret == Result::SUCCESS) {
2799         functionCoverage->isBlockCoverage_ = isBlockCoverage;
2800     } else {
2801         error += "Unknown 'isBlockCoverage';";
2802     }
2803 
2804     if (!error.empty()) {
2805         LOG_DEBUGGER(ERROR) << "FunctionCoverage::Create " << error;
2806         return nullptr;
2807     }
2808 
2809     return functionCoverage;
2810 }
2811 
ToJson() const2812 std::unique_ptr<PtJson> FunctionCoverage::ToJson() const
2813 {
2814     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2815 
2816     result->Add("functionName", functionName_.c_str());
2817 
2818     std::unique_ptr<PtJson> ranges = PtJson::CreateArray();
2819     size_t len = ranges_.size();
2820     for (size_t i = 0; i < len; i++) {
2821         ASSERT(ranges_[i] != nullptr);
2822         ranges->Push(ranges_[i]->ToJson());
2823     }
2824     result->Add("ranges", ranges);
2825 
2826     result->Add("isBlockCoverage", isBlockCoverage_);
2827 
2828     return result;
2829 }
2830 
Create(const PtJson & params)2831 std::unique_ptr<ScriptCoverage> ScriptCoverage::Create(const PtJson &params)
2832 {
2833     std::string error;
2834     auto scriptCoverage = std::make_unique<ScriptCoverage>();
2835     Result ret;
2836 
2837     std::string scriptId;
2838     ret = params.GetString("scriptId", &scriptId);
2839     if (ret == Result::SUCCESS) {
2840         scriptCoverage->scriptId_ = std::move(scriptId);
2841     } else {
2842         error += "Unknown 'scriptId';";
2843     }
2844 
2845     std::string url;
2846     ret = params.GetString("url", &url);
2847     if (ret == Result::SUCCESS) {
2848         scriptCoverage->url_ = std::move(url);
2849     } else {
2850         error += "Unknown 'url';";
2851     }
2852 
2853     std::unique_ptr<PtJson> functions;
2854     ret = params.GetArray("functions", &functions);
2855     if (ret == Result::SUCCESS) {
2856         int32_t len = functions->GetSize();
2857         for (int32_t i = 0; i < len; ++i) {
2858             std::unique_ptr<PtJson> arrayEle = functions->Get(i);
2859             ASSERT(arrayEle != nullptr);
2860             std::unique_ptr<FunctionCoverage> pFunctions = FunctionCoverage::Create(*arrayEle);
2861             if (pFunctions == nullptr) {
2862                 error += "'functions' format invalid;";
2863             } else {
2864                 scriptCoverage->functions_.emplace_back(std::move(pFunctions));
2865             }
2866         }
2867     } else {
2868         error += "Unknown 'functions';";
2869     }
2870 
2871     if (!error.empty()) {
2872         LOG_DEBUGGER(ERROR) << "ScriptCoverage::Create " << error;
2873         return nullptr;
2874     }
2875 
2876     return scriptCoverage;
2877 }
2878 
ToJson() const2879 std::unique_ptr<PtJson> ScriptCoverage::ToJson() const
2880 {
2881     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2882 
2883     result->Add("scriptId", scriptId_.c_str());
2884     result->Add("url", url_.c_str());
2885 
2886     std::unique_ptr<PtJson> functions = PtJson::CreateArray();
2887     size_t len = functions_.size();
2888     for (size_t i = 0; i < len; i++) {
2889         ASSERT(functions_[i] != nullptr);
2890         functions->Push(functions_[i]->ToJson());
2891     }
2892     result->Add("functions", functions);
2893 
2894     return result;
2895 }
2896 
Create(const PtJson & params)2897 std::unique_ptr<TypeObject> TypeObject::Create(const PtJson &params)
2898 {
2899     std::string error;
2900     auto typeObject = std::make_unique<TypeObject>();
2901     Result ret;
2902 
2903     std::string name;
2904     ret = params.GetString("name", &name);
2905     if (ret == Result::SUCCESS) {
2906         typeObject->name_ = std::move(name);
2907     } else {
2908         error += "Unknown 'name';";
2909     }
2910 
2911     if (!error.empty()) {
2912         LOG_DEBUGGER(ERROR) << "TypeObject::Create " << error;
2913         return nullptr;
2914     }
2915 
2916     return typeObject;
2917 }
2918 
ToJson() const2919 std::unique_ptr<PtJson> TypeObject::ToJson() const
2920 {
2921     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2922 
2923     result->Add("name", name_.c_str());
2924 
2925     return result;
2926 }
2927 
Create(const PtJson & params)2928 std::unique_ptr<TypeProfileEntry> TypeProfileEntry::Create(const PtJson &params)
2929 {
2930     std::string error;
2931     auto typeProfileEntry = std::make_unique<TypeProfileEntry>();
2932     Result ret;
2933 
2934     int32_t offset;
2935     ret = params.GetInt("offset", &offset);
2936     if (ret == Result::SUCCESS) {
2937         typeProfileEntry->offset_ = offset;
2938     } else {
2939         error += "Unknown 'offset';";
2940     }
2941 
2942     std::unique_ptr<PtJson> types;
2943     ret = params.GetArray("types", &types);
2944     if (ret == Result::SUCCESS) {
2945         int32_t len = types->GetSize();
2946         for (int32_t i = 0; i < len; ++i) {
2947             std::unique_ptr<PtJson> arrayEle = types->Get(i);
2948             ASSERT(arrayEle != nullptr);
2949             std::unique_ptr<TypeObject> pTypes = TypeObject::Create(*arrayEle);
2950             if (pTypes == nullptr) {
2951                 error += "'types' format invalid;";
2952             } else {
2953                 typeProfileEntry->types_.emplace_back(std::move(pTypes));
2954             }
2955         }
2956     } else {
2957         error += "Unknown 'types';";
2958     }
2959 
2960     if (!error.empty()) {
2961         LOG_DEBUGGER(ERROR) << "TypeProfileEntry::Create " << error;
2962         return nullptr;
2963     }
2964 
2965     return typeProfileEntry;
2966 }
2967 
ToJson() const2968 std::unique_ptr<PtJson> TypeProfileEntry::ToJson() const
2969 {
2970     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2971 
2972     result->Add("offset", offset_);
2973 
2974     std::unique_ptr<PtJson> types = PtJson::CreateArray();
2975     size_t len = types_.size();
2976     for (size_t i = 0; i < len; i++) {
2977         ASSERT(types_[i] != nullptr);
2978         types->Push(types_[i]->ToJson());
2979     }
2980     result->Add("types", types);
2981 
2982     return result;
2983 }
2984 
Create(const PtJson & params)2985 std::unique_ptr<ScriptTypeProfile> ScriptTypeProfile::Create(const PtJson &params)
2986 {
2987     std::string error;
2988     auto scriptTypeProfile = std::make_unique<ScriptTypeProfile>();
2989     Result ret;
2990 
2991     std::string scriptId;
2992     ret = params.GetString("scriptId", &scriptId);
2993     if (ret == Result::SUCCESS) {
2994         scriptTypeProfile->scriptId_ = std::move(scriptId);
2995     } else {
2996         error += "Unknown 'scriptId';";
2997     }
2998 
2999     std::string url;
3000     ret = params.GetString("url", &url);
3001     if (ret == Result::SUCCESS) {
3002         scriptTypeProfile->url_ = std::move(url);
3003     } else {
3004         error += "Unknown 'url';";
3005     }
3006 
3007     std::unique_ptr<PtJson> entries;
3008     ret = params.GetArray("entries", &entries);
3009     if (ret == Result::SUCCESS) {
3010         int32_t len = entries->GetSize();
3011         for (int32_t i = 0; i < len; ++i) {
3012             std::unique_ptr<PtJson> arrayEle = entries->Get(i);
3013             ASSERT(arrayEle != nullptr);
3014             std::unique_ptr<TypeProfileEntry> pEntries = TypeProfileEntry::Create(*arrayEle);
3015             if (pEntries == nullptr) {
3016                 error += "'entries' format invalid;";
3017             } else {
3018                 scriptTypeProfile->entries_.emplace_back(std::move(pEntries));
3019             }
3020         }
3021     } else {
3022         error += "Unknown 'entries';";
3023     }
3024 
3025     if (!error.empty()) {
3026         LOG_DEBUGGER(ERROR) << "ScriptTypeProfile::Create " << error;
3027         return nullptr;
3028     }
3029 
3030     return scriptTypeProfile;
3031 }
3032 
ToJson() const3033 std::unique_ptr<PtJson> ScriptTypeProfile::ToJson() const
3034 {
3035     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3036 
3037     result->Add("scriptId", scriptId_.c_str());
3038     result->Add("url", url_.c_str());
3039 
3040     std::unique_ptr<PtJson> entries = PtJson::CreateArray();
3041     size_t len = entries_.size();
3042     for (size_t i = 0; i < len; i++) {
3043         ASSERT(entries_[i] != nullptr);
3044         entries->Push(entries_[i]->ToJson());
3045     }
3046     result->Add("entries", entries);
3047 
3048     return result;
3049 }
3050 
Create(const PtJson & params)3051 std::unique_ptr<TraceConfig> TraceConfig::Create(const PtJson &params)
3052 {
3053     std::string error;
3054     auto traceConfig = std::make_unique<TraceConfig>();
3055     Result ret;
3056 
3057     std::string recordMode;
3058     ret = params.GetString("recordMode", &recordMode);
3059     if (ret == Result::SUCCESS) {
3060         if (TraceConfig::RecordModeValues::Valid(recordMode)) {
3061             traceConfig->recordMode_ = std::move(recordMode);
3062         } else {
3063             error += "'recordMode' is invalid;";
3064         }
3065     } else if (ret == Result::TYPE_ERROR) {
3066         error += "Unknown 'recordMode';";
3067     }
3068 
3069     bool enableSampling = false;
3070     ret = params.GetBool("enableSampling", &enableSampling);
3071     if (ret == Result::SUCCESS) {
3072         traceConfig->enableSampling_ = enableSampling;
3073     } else if (ret == Result::TYPE_ERROR) {
3074         error += "Unknown 'enableSampling';";
3075     }
3076 
3077     bool enableSystrace = false;
3078     ret = params.GetBool("enableSystrace", &enableSystrace);
3079     if (ret == Result::SUCCESS) {
3080         traceConfig->enableSystrace_ = enableSystrace;
3081     } else if (ret == Result::TYPE_ERROR) {
3082         error += "Unknown 'enableSystrace';";
3083     }
3084 
3085     bool enableArgumentFilter = false;
3086     ret = params.GetBool("enableArgumentFilter", &enableArgumentFilter);
3087     if (ret == Result::SUCCESS) {
3088         traceConfig->enableArgumentFilter_ = enableArgumentFilter;
3089     } else if (ret == Result::TYPE_ERROR) {
3090         error += "Unknown 'enableArgumentFilter';";
3091     }
3092 
3093     std::unique_ptr<PtJson> includedCategories;
3094     ret = params.GetArray("includedCategories", &includedCategories);
3095     if (ret == Result::SUCCESS) {
3096         int32_t includedCategoriesLen = includedCategories->GetSize();
3097         for (int32_t i = 0; i < includedCategoriesLen; ++i) {
3098             std::string pIncludedCategories = includedCategories->Get(i)->GetString();
3099             traceConfig->includedCategories_.value().emplace_back(pIncludedCategories);
3100         }
3101     }  else if (ret == Result::TYPE_ERROR) {
3102         error += "Unknown 'includedCategories';";
3103     }
3104 
3105     std::unique_ptr<PtJson> excludedCategories;
3106     ret = params.GetArray("excludedCategories", &excludedCategories);
3107     if (ret == Result::SUCCESS) {
3108         int32_t excludedCategoriesLen = excludedCategories->GetSize();
3109         for (int32_t i = 0; i < excludedCategoriesLen; ++i) {
3110             std::string pExcludedCategories = excludedCategories->Get(i)->GetString();
3111             traceConfig->excludedCategories_.value().emplace_back(pExcludedCategories);
3112         }
3113     }  else if (ret == Result::TYPE_ERROR) {
3114         error += "Unknown 'excludedCategories';";
3115     }
3116 
3117     std::unique_ptr<PtJson> syntheticDelays;
3118     ret = params.GetArray("syntheticDelays", &syntheticDelays);
3119     if (ret == Result::SUCCESS) {
3120         int32_t syntheticDelaysLen = includedCategories->GetSize();
3121         for (int32_t i = 0; i < syntheticDelaysLen; ++i) {
3122             std::string pSyntheticDelays = syntheticDelays->Get(i)->GetString();
3123             traceConfig->syntheticDelays_.value().emplace_back(pSyntheticDelays);
3124         }
3125     }  else if (ret == Result::TYPE_ERROR) {
3126         error += "Unknown 'syntheticDelays';";
3127     }
3128 
3129     std::unique_ptr<PtJson> memoryDumpConfig;
3130     ret = params.GetObject("memoryDumpConfig", &memoryDumpConfig);
3131     if (ret == Result::SUCCESS) {
3132         std::unique_ptr<MemoryDumpConfig> tmpMemory = std::move(memoryDumpConfig);
3133         if (tmpMemory == nullptr) {
3134             error += "'memoryDumpConfig' format error;";
3135         } else {
3136             traceConfig->memoryDumpConfig_ = std::move(tmpMemory);
3137         }
3138     } else if (ret == Result::TYPE_ERROR) {
3139         error += "Unknown 'memoryDumpConfig';";
3140     }
3141 
3142     if (!error.empty()) {
3143         LOG_DEBUGGER(ERROR) << "TraceConfig::Create " << error;
3144         return nullptr;
3145     }
3146 
3147     return traceConfig;
3148 }
3149 
ToJson() const3150 std::unique_ptr<PtJson> TraceConfig::ToJson() const
3151 {
3152     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3153 
3154     if (recordMode_) {
3155         result->Add("recordMode", recordMode_.value().c_str());
3156     }
3157 
3158     if (enableSampling_) {
3159         result->Add("enableSampling", enableSampling_.value());
3160     }
3161 
3162     if (enableSystrace_) {
3163         result->Add("enableSystrace", enableSystrace_.value());
3164     }
3165 
3166     if (enableArgumentFilter_) {
3167         result->Add("enableArgumentFilter", enableArgumentFilter_.value());
3168     }
3169 
3170     if (includedCategories_) {
3171         std::unique_ptr<PtJson> includedCategories = PtJson::CreateArray();
3172         size_t includedCategoriesLen = includedCategories_->size();
3173         for (size_t i = 0; i < includedCategoriesLen; i++) {
3174             includedCategories->Push(includedCategories_.value()[i].c_str());
3175         }
3176         result->Add("includedCategories", includedCategories);
3177     }
3178 
3179     if (excludedCategories_) {
3180         std::unique_ptr<PtJson> excludedCategories = PtJson::CreateArray();
3181         size_t excludedCategoriesLen = excludedCategories_->size();
3182         for (size_t i = 0; i < excludedCategoriesLen; i++) {
3183             excludedCategories->Push(excludedCategories_.value()[i].c_str());
3184         }
3185         result->Add("excludedCategories", excludedCategories);
3186     }
3187 
3188     if (syntheticDelays_) {
3189         std::unique_ptr<PtJson> syntheticDelays = PtJson::CreateArray();
3190         size_t syntheticDelaysLen = syntheticDelays_->size();
3191         for (size_t i = 0; i < syntheticDelaysLen; i++) {
3192             syntheticDelays->Push(syntheticDelays_.value()[i].c_str());
3193         }
3194         result->Add("syntheticDelays", syntheticDelays);
3195     }
3196 
3197     if (memoryDumpConfig_) {
3198         result->Add("functionLocation", memoryDumpConfig_.value());
3199     }
3200 
3201     return result;
3202 }
3203 
Create(const PtJson & params)3204 std::unique_ptr<BreakpointInfo> BreakpointInfo::Create(const PtJson &params)
3205 {
3206     auto paramsObject = std::make_unique<BreakpointInfo>();
3207     std::string error;
3208     Result ret;
3209     // lineNumber
3210     int32_t lineNumber;
3211     ret = params.GetInt("lineNumber", &lineNumber);
3212     if (ret == Result::SUCCESS) {
3213         paramsObject->lineNumber_ = lineNumber;
3214     } else {
3215         error += "Unknown 'lineNumber';";
3216     }
3217     // url
3218     std::string url;
3219     ret = params.GetString("url", &url);
3220     if (ret == Result::SUCCESS) {
3221         paramsObject->url_ = std::move(url);
3222     } else if (ret == Result::TYPE_ERROR) {
3223         error += "Unknown 'url';";
3224     }
3225     // columnNumber
3226     int32_t columnNumber;
3227     ret = params.GetInt("columnNumber", &columnNumber);
3228     if (ret == Result::SUCCESS) {
3229         paramsObject->columnNumber_ = columnNumber;
3230     } else if (ret == Result::TYPE_ERROR) {
3231         error += "Unknown 'columnNumber';";
3232     }
3233     // condition
3234     std::string condition;
3235     ret = params.GetString("condition", &condition);
3236     if (ret == Result::SUCCESS) {
3237         paramsObject->condition_ = std::move(condition);
3238     } else if (ret == Result::TYPE_ERROR) {
3239         error += "Unknown 'condition';";
3240     }
3241     // urlRegex
3242     std::string urlRegex;
3243     ret = params.GetString("urlRegex", &urlRegex);
3244     if (ret == Result::SUCCESS) {
3245         paramsObject->urlRegex_ = std::move(urlRegex);
3246     } else if (ret == Result::TYPE_ERROR) {
3247         error += "Unknown 'urlRegex';";
3248     }
3249     // scriptHash
3250     std::string scriptHash;
3251     ret = params.GetString("scriptHash", &scriptHash);
3252     if (ret == Result::SUCCESS) {
3253         paramsObject->scriptHash_ = std::move(scriptHash);
3254     } else if (ret == Result::TYPE_ERROR) {
3255         error += "Unknown 'scriptHash';";
3256     }
3257     // restrictToFunction
3258     bool restrictToFunction = false;
3259     ret = params.GetBool("restrictToFunction", &restrictToFunction);
3260     if (ret == Result::SUCCESS) {
3261         paramsObject->restrictToFunction_ = restrictToFunction;
3262     } else if (ret == Result::TYPE_ERROR) {  // optional value
3263         error += "Unknown 'restrictToFunction';";
3264     }
3265 
3266     if (!error.empty()) {
3267         LOG_DEBUGGER(ERROR) << "BreakpointInfo::Create " << error;
3268         return nullptr;
3269     }
3270     return paramsObject;
3271 }
3272 
ToJson() const3273 std::unique_ptr<PtJson> BreakpointInfo::ToJson() const
3274 {
3275     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3276     result->Add("lineNumber", lineNumber_);
3277     result->Add("columnNumber", columnNumber_);
3278     result->Add("url", url_.c_str());
3279     if (condition_) {
3280         result->Add("condition", condition_.value().c_str());
3281     }
3282     if (urlRegex_) {
3283         result->Add("urlRegex", urlRegex_.value().c_str());
3284     }
3285     if (scriptHash_) {
3286         result->Add("scriptHash", scriptHash_.value().c_str());
3287     }
3288     if (restrictToFunction_) {
3289         result->Add("restrictToFunction", restrictToFunction_.value());
3290     }
3291 
3292     return result;
3293 }
3294 
Create(const PtJson & params)3295 std::unique_ptr<BreakpointReturnInfo> BreakpointReturnInfo::Create(const PtJson &params)
3296 {
3297     auto paramsObject = std::make_unique<BreakpointReturnInfo>();
3298     std::string error;
3299     Result ret;
3300     // lineNumber
3301     int32_t lineNumber;
3302     ret = params.GetInt("lineNumber", &lineNumber);
3303     if (ret == Result::SUCCESS) {
3304         paramsObject->lineNumber_ = lineNumber;
3305     } else {
3306         error += "Unknown 'lineNumber';";
3307     }
3308     // columnNumber
3309     int32_t columnNumber;
3310     ret = params.GetInt("columnNumber", &columnNumber);
3311     if (ret == Result::SUCCESS) {
3312         paramsObject->columnNumber_ = columnNumber;
3313     } else if (ret == Result::TYPE_ERROR) {
3314         error += "Unknown 'columnNumber';";
3315     }
3316     // id
3317     std::string id;
3318     ret = params.GetString("id", &id);
3319     if (ret == Result::SUCCESS) {
3320         paramsObject->id_ = std::move(id);
3321     } else if (ret == Result::TYPE_ERROR) {
3322         error += "Unknown 'id';";
3323     }
3324     // scriptId
3325     int32_t scriptId;
3326     ret = params.GetInt("scriptId", &scriptId);
3327     if (ret == Result::SUCCESS) {
3328         paramsObject->scriptId_ = scriptId;
3329     } else if (ret == Result::TYPE_ERROR) {
3330         error += "Unknown 'scriptId';";
3331     }
3332 
3333     if (!error.empty()) {
3334         LOG_DEBUGGER(ERROR) << "BreakpointReturnInfo::Create " << error;
3335         return nullptr;
3336     }
3337 
3338     return paramsObject;
3339 }
3340 
ToJson() const3341 std::unique_ptr<PtJson> BreakpointReturnInfo::ToJson() const
3342 {
3343     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3344     result->Add("lineNumber", lineNumber_);
3345     result->Add("columnNumber", columnNumber_);
3346     result->Add("id", id_.c_str());
3347     result->Add("scriptId", scriptId_);
3348 
3349     return result;
3350 }
3351 }  // namespace panda::ecmascript::tooling
3352