• 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