11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/inspector/custom-preview.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "../../third_party/inspector_protocol/crdtp/json.h"
81cb0ef41Sopenharmony_ci#include "include/v8-container.h"
91cb0ef41Sopenharmony_ci#include "include/v8-context.h"
101cb0ef41Sopenharmony_ci#include "include/v8-function.h"
111cb0ef41Sopenharmony_ci#include "include/v8-json.h"
121cb0ef41Sopenharmony_ci#include "include/v8-microtask-queue.h"
131cb0ef41Sopenharmony_ci#include "src/debug/debug-interface.h"
141cb0ef41Sopenharmony_ci#include "src/inspector/injected-script.h"
151cb0ef41Sopenharmony_ci#include "src/inspector/inspected-context.h"
161cb0ef41Sopenharmony_ci#include "src/inspector/string-util.h"
171cb0ef41Sopenharmony_ci#include "src/inspector/v8-console-message.h"
181cb0ef41Sopenharmony_ci#include "src/inspector/v8-inspector-impl.h"
191cb0ef41Sopenharmony_ci#include "src/inspector/v8-stack-trace-impl.h"
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cinamespace v8_inspector {
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciusing protocol::Runtime::CustomPreview;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_cinamespace {
261cb0ef41Sopenharmony_civoid reportError(v8::Local<v8::Context> context, const v8::TryCatch& tryCatch) {
271cb0ef41Sopenharmony_ci  DCHECK(tryCatch.HasCaught());
281cb0ef41Sopenharmony_ci  v8::Isolate* isolate = context->GetIsolate();
291cb0ef41Sopenharmony_ci  V8InspectorImpl* inspector =
301cb0ef41Sopenharmony_ci      static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
311cb0ef41Sopenharmony_ci  int contextId = InspectedContext::contextId(context);
321cb0ef41Sopenharmony_ci  int groupId = inspector->contextGroupId(contextId);
331cb0ef41Sopenharmony_ci  v8::Local<v8::String> message = tryCatch.Message()->Get();
341cb0ef41Sopenharmony_ci  v8::Local<v8::String> prefix =
351cb0ef41Sopenharmony_ci      toV8String(isolate, "Custom Formatter Failed: ");
361cb0ef41Sopenharmony_ci  message = v8::String::Concat(isolate, prefix, message);
371cb0ef41Sopenharmony_ci  std::vector<v8::Local<v8::Value>> arguments;
381cb0ef41Sopenharmony_ci  arguments.push_back(message);
391cb0ef41Sopenharmony_ci  V8ConsoleMessageStorage* storage =
401cb0ef41Sopenharmony_ci      inspector->ensureConsoleMessageStorage(groupId);
411cb0ef41Sopenharmony_ci  if (!storage) return;
421cb0ef41Sopenharmony_ci  storage->addMessage(V8ConsoleMessage::createForConsoleAPI(
431cb0ef41Sopenharmony_ci      context, contextId, groupId, inspector,
441cb0ef41Sopenharmony_ci      inspector->client()->currentTimeMS(), ConsoleAPIType::kError, arguments,
451cb0ef41Sopenharmony_ci      String16(), nullptr));
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_civoid reportError(v8::Local<v8::Context> context, const v8::TryCatch& tryCatch,
491cb0ef41Sopenharmony_ci                 const String16& message) {
501cb0ef41Sopenharmony_ci  v8::Isolate* isolate = context->GetIsolate();
511cb0ef41Sopenharmony_ci  isolate->ThrowException(toV8String(isolate, message));
521cb0ef41Sopenharmony_ci  reportError(context, tryCatch);
531cb0ef41Sopenharmony_ci}
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ciInjectedScript* getInjectedScript(v8::Local<v8::Context> context,
561cb0ef41Sopenharmony_ci                                  int sessionId) {
571cb0ef41Sopenharmony_ci  v8::Isolate* isolate = context->GetIsolate();
581cb0ef41Sopenharmony_ci  V8InspectorImpl* inspector =
591cb0ef41Sopenharmony_ci      static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
601cb0ef41Sopenharmony_ci  InspectedContext* inspectedContext =
611cb0ef41Sopenharmony_ci      inspector->getContext(InspectedContext::contextId(context));
621cb0ef41Sopenharmony_ci  if (!inspectedContext) return nullptr;
631cb0ef41Sopenharmony_ci  return inspectedContext->getInjectedScript(sessionId);
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_cibool substituteObjectTags(int sessionId, const String16& groupName,
671cb0ef41Sopenharmony_ci                          v8::Local<v8::Context> context,
681cb0ef41Sopenharmony_ci                          v8::Local<v8::Array> jsonML, int maxDepth) {
691cb0ef41Sopenharmony_ci  if (!jsonML->Length()) return true;
701cb0ef41Sopenharmony_ci  v8::Isolate* isolate = context->GetIsolate();
711cb0ef41Sopenharmony_ci  v8::TryCatch tryCatch(isolate);
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  if (maxDepth <= 0) {
741cb0ef41Sopenharmony_ci    reportError(context, tryCatch,
751cb0ef41Sopenharmony_ci                "Too deep hierarchy of inlined custom previews");
761cb0ef41Sopenharmony_ci    return false;
771cb0ef41Sopenharmony_ci  }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  v8::Local<v8::Value> firstValue;
801cb0ef41Sopenharmony_ci  if (!jsonML->Get(context, 0).ToLocal(&firstValue)) {
811cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
821cb0ef41Sopenharmony_ci    return false;
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci  v8::Local<v8::String> objectLiteral = toV8String(isolate, "object");
851cb0ef41Sopenharmony_ci  if (jsonML->Length() == 2 && firstValue->IsString() &&
861cb0ef41Sopenharmony_ci      firstValue.As<v8::String>()->StringEquals(objectLiteral)) {
871cb0ef41Sopenharmony_ci    v8::Local<v8::Value> attributesValue;
881cb0ef41Sopenharmony_ci    if (!jsonML->Get(context, 1).ToLocal(&attributesValue)) {
891cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
901cb0ef41Sopenharmony_ci      return false;
911cb0ef41Sopenharmony_ci    }
921cb0ef41Sopenharmony_ci    if (!attributesValue->IsObject()) {
931cb0ef41Sopenharmony_ci      reportError(context, tryCatch, "attributes should be an Object");
941cb0ef41Sopenharmony_ci      return false;
951cb0ef41Sopenharmony_ci    }
961cb0ef41Sopenharmony_ci    v8::Local<v8::Object> attributes = attributesValue.As<v8::Object>();
971cb0ef41Sopenharmony_ci    v8::Local<v8::Value> originValue;
981cb0ef41Sopenharmony_ci    if (!attributes->Get(context, objectLiteral).ToLocal(&originValue)) {
991cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
1001cb0ef41Sopenharmony_ci      return false;
1011cb0ef41Sopenharmony_ci    }
1021cb0ef41Sopenharmony_ci    if (originValue->IsUndefined()) {
1031cb0ef41Sopenharmony_ci      reportError(context, tryCatch,
1041cb0ef41Sopenharmony_ci                  "obligatory attribute \"object\" isn't specified");
1051cb0ef41Sopenharmony_ci      return false;
1061cb0ef41Sopenharmony_ci    }
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci    v8::Local<v8::Value> configValue;
1091cb0ef41Sopenharmony_ci    if (!attributes->Get(context, toV8String(isolate, "config"))
1101cb0ef41Sopenharmony_ci             .ToLocal(&configValue)) {
1111cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
1121cb0ef41Sopenharmony_ci      return false;
1131cb0ef41Sopenharmony_ci    }
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci    InjectedScript* injectedScript = getInjectedScript(context, sessionId);
1161cb0ef41Sopenharmony_ci    if (!injectedScript) {
1171cb0ef41Sopenharmony_ci      reportError(context, tryCatch, "cannot find context with specified id");
1181cb0ef41Sopenharmony_ci      return false;
1191cb0ef41Sopenharmony_ci    }
1201cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Runtime::RemoteObject> wrapper;
1211cb0ef41Sopenharmony_ci    protocol::Response response =
1221cb0ef41Sopenharmony_ci        injectedScript->wrapObject(originValue, groupName, WrapMode::kNoPreview,
1231cb0ef41Sopenharmony_ci                                   configValue, maxDepth - 1, &wrapper);
1241cb0ef41Sopenharmony_ci    if (!response.IsSuccess() || !wrapper) {
1251cb0ef41Sopenharmony_ci      reportError(context, tryCatch, "cannot wrap value");
1261cb0ef41Sopenharmony_ci      return false;
1271cb0ef41Sopenharmony_ci    }
1281cb0ef41Sopenharmony_ci    std::vector<uint8_t> json;
1291cb0ef41Sopenharmony_ci    v8_crdtp::json::ConvertCBORToJSON(v8_crdtp::SpanFrom(wrapper->Serialize()),
1301cb0ef41Sopenharmony_ci                                      &json);
1311cb0ef41Sopenharmony_ci    v8::Local<v8::Value> jsonWrapper;
1321cb0ef41Sopenharmony_ci    v8_inspector::StringView serialized(json.data(), json.size());
1331cb0ef41Sopenharmony_ci    if (!v8::JSON::Parse(context, toV8String(isolate, serialized))
1341cb0ef41Sopenharmony_ci             .ToLocal(&jsonWrapper)) {
1351cb0ef41Sopenharmony_ci      reportError(context, tryCatch, "cannot wrap value");
1361cb0ef41Sopenharmony_ci      return false;
1371cb0ef41Sopenharmony_ci    }
1381cb0ef41Sopenharmony_ci    if (jsonML->Set(context, 1, jsonWrapper).IsNothing()) {
1391cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
1401cb0ef41Sopenharmony_ci      return false;
1411cb0ef41Sopenharmony_ci    }
1421cb0ef41Sopenharmony_ci  } else {
1431cb0ef41Sopenharmony_ci    for (uint32_t i = 0; i < jsonML->Length(); ++i) {
1441cb0ef41Sopenharmony_ci      v8::Local<v8::Value> value;
1451cb0ef41Sopenharmony_ci      if (!jsonML->Get(context, i).ToLocal(&value)) {
1461cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
1471cb0ef41Sopenharmony_ci        return false;
1481cb0ef41Sopenharmony_ci      }
1491cb0ef41Sopenharmony_ci      if (value->IsArray() && value.As<v8::Array>()->Length() > 0 &&
1501cb0ef41Sopenharmony_ci          !substituteObjectTags(sessionId, groupName, context,
1511cb0ef41Sopenharmony_ci                                value.As<v8::Array>(), maxDepth - 1)) {
1521cb0ef41Sopenharmony_ci        return false;
1531cb0ef41Sopenharmony_ci      }
1541cb0ef41Sopenharmony_ci    }
1551cb0ef41Sopenharmony_ci  }
1561cb0ef41Sopenharmony_ci  return true;
1571cb0ef41Sopenharmony_ci}
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_civoid bodyCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
1601cb0ef41Sopenharmony_ci  v8::Isolate* isolate = info.GetIsolate();
1611cb0ef41Sopenharmony_ci  v8::TryCatch tryCatch(isolate);
1621cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context = isolate->GetCurrentContext();
1631cb0ef41Sopenharmony_ci  v8::Local<v8::Object> bodyConfig = info.Data().As<v8::Object>();
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  v8::Local<v8::Value> objectValue;
1661cb0ef41Sopenharmony_ci  if (!bodyConfig->Get(context, toV8String(isolate, "object"))
1671cb0ef41Sopenharmony_ci           .ToLocal(&objectValue)) {
1681cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
1691cb0ef41Sopenharmony_ci    return;
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci  if (!objectValue->IsObject()) {
1721cb0ef41Sopenharmony_ci    reportError(context, tryCatch, "object should be an Object");
1731cb0ef41Sopenharmony_ci    return;
1741cb0ef41Sopenharmony_ci  }
1751cb0ef41Sopenharmony_ci  v8::Local<v8::Object> object = objectValue.As<v8::Object>();
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  v8::Local<v8::Value> formatterValue;
1781cb0ef41Sopenharmony_ci  if (!bodyConfig->Get(context, toV8String(isolate, "formatter"))
1791cb0ef41Sopenharmony_ci           .ToLocal(&formatterValue)) {
1801cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
1811cb0ef41Sopenharmony_ci    return;
1821cb0ef41Sopenharmony_ci  }
1831cb0ef41Sopenharmony_ci  if (!formatterValue->IsObject()) {
1841cb0ef41Sopenharmony_ci    reportError(context, tryCatch, "formatter should be an Object");
1851cb0ef41Sopenharmony_ci    return;
1861cb0ef41Sopenharmony_ci  }
1871cb0ef41Sopenharmony_ci  v8::Local<v8::Object> formatter = formatterValue.As<v8::Object>();
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci  v8::Local<v8::Value> bodyValue;
1901cb0ef41Sopenharmony_ci  if (!formatter->Get(context, toV8String(isolate, "body"))
1911cb0ef41Sopenharmony_ci           .ToLocal(&bodyValue)) {
1921cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
1931cb0ef41Sopenharmony_ci    return;
1941cb0ef41Sopenharmony_ci  }
1951cb0ef41Sopenharmony_ci  if (!bodyValue->IsFunction()) {
1961cb0ef41Sopenharmony_ci    reportError(context, tryCatch, "body should be a Function");
1971cb0ef41Sopenharmony_ci    return;
1981cb0ef41Sopenharmony_ci  }
1991cb0ef41Sopenharmony_ci  v8::Local<v8::Function> bodyFunction = bodyValue.As<v8::Function>();
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  v8::Local<v8::Value> configValue;
2021cb0ef41Sopenharmony_ci  if (!bodyConfig->Get(context, toV8String(isolate, "config"))
2031cb0ef41Sopenharmony_ci           .ToLocal(&configValue)) {
2041cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
2051cb0ef41Sopenharmony_ci    return;
2061cb0ef41Sopenharmony_ci  }
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  v8::Local<v8::Value> sessionIdValue;
2091cb0ef41Sopenharmony_ci  if (!bodyConfig->Get(context, toV8String(isolate, "sessionId"))
2101cb0ef41Sopenharmony_ci           .ToLocal(&sessionIdValue)) {
2111cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
2121cb0ef41Sopenharmony_ci    return;
2131cb0ef41Sopenharmony_ci  }
2141cb0ef41Sopenharmony_ci  if (!sessionIdValue->IsInt32()) {
2151cb0ef41Sopenharmony_ci    reportError(context, tryCatch, "sessionId should be an Int32");
2161cb0ef41Sopenharmony_ci    return;
2171cb0ef41Sopenharmony_ci  }
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci  v8::Local<v8::Value> groupNameValue;
2201cb0ef41Sopenharmony_ci  if (!bodyConfig->Get(context, toV8String(isolate, "groupName"))
2211cb0ef41Sopenharmony_ci           .ToLocal(&groupNameValue)) {
2221cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
2231cb0ef41Sopenharmony_ci    return;
2241cb0ef41Sopenharmony_ci  }
2251cb0ef41Sopenharmony_ci  if (!groupNameValue->IsString()) {
2261cb0ef41Sopenharmony_ci    reportError(context, tryCatch, "groupName should be a string");
2271cb0ef41Sopenharmony_ci    return;
2281cb0ef41Sopenharmony_ci  }
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  v8::Local<v8::Value> formattedValue;
2311cb0ef41Sopenharmony_ci  v8::Local<v8::Value> args[] = {object, configValue};
2321cb0ef41Sopenharmony_ci  if (!bodyFunction->Call(context, formatter, 2, args)
2331cb0ef41Sopenharmony_ci           .ToLocal(&formattedValue)) {
2341cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
2351cb0ef41Sopenharmony_ci    return;
2361cb0ef41Sopenharmony_ci  }
2371cb0ef41Sopenharmony_ci  if (!formattedValue->IsArray()) {
2381cb0ef41Sopenharmony_ci    reportError(context, tryCatch, "body should return an Array");
2391cb0ef41Sopenharmony_ci    return;
2401cb0ef41Sopenharmony_ci  }
2411cb0ef41Sopenharmony_ci  v8::Local<v8::Array> jsonML = formattedValue.As<v8::Array>();
2421cb0ef41Sopenharmony_ci  if (jsonML->Length() &&
2431cb0ef41Sopenharmony_ci      !substituteObjectTags(
2441cb0ef41Sopenharmony_ci          sessionIdValue.As<v8::Int32>()->Value(),
2451cb0ef41Sopenharmony_ci          toProtocolString(isolate, groupNameValue.As<v8::String>()), context,
2461cb0ef41Sopenharmony_ci          jsonML, kMaxCustomPreviewDepth)) {
2471cb0ef41Sopenharmony_ci    return;
2481cb0ef41Sopenharmony_ci  }
2491cb0ef41Sopenharmony_ci  info.GetReturnValue().Set(jsonML);
2501cb0ef41Sopenharmony_ci}
2511cb0ef41Sopenharmony_ci}  // anonymous namespace
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_civoid generateCustomPreview(int sessionId, const String16& groupName,
2541cb0ef41Sopenharmony_ci                           v8::Local<v8::Object> object,
2551cb0ef41Sopenharmony_ci                           v8::MaybeLocal<v8::Value> maybeConfig, int maxDepth,
2561cb0ef41Sopenharmony_ci                           std::unique_ptr<CustomPreview>* preview) {
2571cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context;
2581cb0ef41Sopenharmony_ci  if (!object->GetCreationContext().ToLocal(&context)) {
2591cb0ef41Sopenharmony_ci    return;
2601cb0ef41Sopenharmony_ci  }
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci  v8::Isolate* isolate = context->GetIsolate();
2631cb0ef41Sopenharmony_ci  v8::MicrotasksScope microtasksScope(isolate,
2641cb0ef41Sopenharmony_ci                                      v8::MicrotasksScope::kDoNotRunMicrotasks);
2651cb0ef41Sopenharmony_ci  v8::TryCatch tryCatch(isolate);
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  v8::Local<v8::Value> configValue;
2681cb0ef41Sopenharmony_ci  if (!maybeConfig.ToLocal(&configValue)) configValue = v8::Undefined(isolate);
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  v8::Local<v8::Object> global = context->Global();
2711cb0ef41Sopenharmony_ci  v8::Local<v8::Value> formattersValue;
2721cb0ef41Sopenharmony_ci  if (!global->Get(context, toV8String(isolate, "devtoolsFormatters"))
2731cb0ef41Sopenharmony_ci           .ToLocal(&formattersValue)) {
2741cb0ef41Sopenharmony_ci    reportError(context, tryCatch);
2751cb0ef41Sopenharmony_ci    return;
2761cb0ef41Sopenharmony_ci  }
2771cb0ef41Sopenharmony_ci  if (!formattersValue->IsArray()) return;
2781cb0ef41Sopenharmony_ci  v8::Local<v8::Array> formatters = formattersValue.As<v8::Array>();
2791cb0ef41Sopenharmony_ci  v8::Local<v8::String> headerLiteral = toV8String(isolate, "header");
2801cb0ef41Sopenharmony_ci  v8::Local<v8::String> hasBodyLiteral = toV8String(isolate, "hasBody");
2811cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < formatters->Length(); ++i) {
2821cb0ef41Sopenharmony_ci    v8::Local<v8::Value> formatterValue;
2831cb0ef41Sopenharmony_ci    if (!formatters->Get(context, i).ToLocal(&formatterValue)) {
2841cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
2851cb0ef41Sopenharmony_ci      return;
2861cb0ef41Sopenharmony_ci    }
2871cb0ef41Sopenharmony_ci    if (!formatterValue->IsObject()) {
2881cb0ef41Sopenharmony_ci      reportError(context, tryCatch, "formatter should be an Object");
2891cb0ef41Sopenharmony_ci      return;
2901cb0ef41Sopenharmony_ci    }
2911cb0ef41Sopenharmony_ci    v8::Local<v8::Object> formatter = formatterValue.As<v8::Object>();
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci    v8::Local<v8::Value> headerValue;
2941cb0ef41Sopenharmony_ci    if (!formatter->Get(context, headerLiteral).ToLocal(&headerValue)) {
2951cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
2961cb0ef41Sopenharmony_ci      return;
2971cb0ef41Sopenharmony_ci    }
2981cb0ef41Sopenharmony_ci    if (!headerValue->IsFunction()) {
2991cb0ef41Sopenharmony_ci      reportError(context, tryCatch, "header should be a Function");
3001cb0ef41Sopenharmony_ci      return;
3011cb0ef41Sopenharmony_ci    }
3021cb0ef41Sopenharmony_ci    v8::Local<v8::Function> headerFunction = headerValue.As<v8::Function>();
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci    v8::Local<v8::Value> formattedValue;
3051cb0ef41Sopenharmony_ci    v8::Local<v8::Value> args[] = {object, configValue};
3061cb0ef41Sopenharmony_ci    if (!headerFunction->Call(context, formatter, 2, args)
3071cb0ef41Sopenharmony_ci             .ToLocal(&formattedValue)) {
3081cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
3091cb0ef41Sopenharmony_ci      return;
3101cb0ef41Sopenharmony_ci    }
3111cb0ef41Sopenharmony_ci    if (!formattedValue->IsArray()) continue;
3121cb0ef41Sopenharmony_ci    v8::Local<v8::Array> jsonML = formattedValue.As<v8::Array>();
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci    v8::Local<v8::Value> hasBodyFunctionValue;
3151cb0ef41Sopenharmony_ci    if (!formatter->Get(context, hasBodyLiteral)
3161cb0ef41Sopenharmony_ci             .ToLocal(&hasBodyFunctionValue)) {
3171cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
3181cb0ef41Sopenharmony_ci      return;
3191cb0ef41Sopenharmony_ci    }
3201cb0ef41Sopenharmony_ci    if (!hasBodyFunctionValue->IsFunction()) continue;
3211cb0ef41Sopenharmony_ci    v8::Local<v8::Function> hasBodyFunction =
3221cb0ef41Sopenharmony_ci        hasBodyFunctionValue.As<v8::Function>();
3231cb0ef41Sopenharmony_ci    v8::Local<v8::Value> hasBodyValue;
3241cb0ef41Sopenharmony_ci    if (!hasBodyFunction->Call(context, formatter, 2, args)
3251cb0ef41Sopenharmony_ci             .ToLocal(&hasBodyValue)) {
3261cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
3271cb0ef41Sopenharmony_ci      return;
3281cb0ef41Sopenharmony_ci    }
3291cb0ef41Sopenharmony_ci    bool hasBody = hasBodyValue->ToBoolean(isolate)->Value();
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci    if (jsonML->Length() && !substituteObjectTags(sessionId, groupName, context,
3321cb0ef41Sopenharmony_ci                                                  jsonML, maxDepth)) {
3331cb0ef41Sopenharmony_ci      return;
3341cb0ef41Sopenharmony_ci    }
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci    v8::Local<v8::String> header;
3371cb0ef41Sopenharmony_ci    if (!v8::JSON::Stringify(context, jsonML).ToLocal(&header)) {
3381cb0ef41Sopenharmony_ci      reportError(context, tryCatch);
3391cb0ef41Sopenharmony_ci      return;
3401cb0ef41Sopenharmony_ci    }
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci    v8::Local<v8::Function> bodyFunction;
3431cb0ef41Sopenharmony_ci    if (hasBody) {
3441cb0ef41Sopenharmony_ci      v8::Local<v8::Object> bodyConfig = v8::Object::New(isolate);
3451cb0ef41Sopenharmony_ci      if (bodyConfig
3461cb0ef41Sopenharmony_ci              ->CreateDataProperty(context, toV8String(isolate, "sessionId"),
3471cb0ef41Sopenharmony_ci                                   v8::Integer::New(isolate, sessionId))
3481cb0ef41Sopenharmony_ci              .IsNothing()) {
3491cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
3501cb0ef41Sopenharmony_ci        return;
3511cb0ef41Sopenharmony_ci      }
3521cb0ef41Sopenharmony_ci      if (bodyConfig
3531cb0ef41Sopenharmony_ci              ->CreateDataProperty(context, toV8String(isolate, "formatter"),
3541cb0ef41Sopenharmony_ci                                   formatter)
3551cb0ef41Sopenharmony_ci              .IsNothing()) {
3561cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
3571cb0ef41Sopenharmony_ci        return;
3581cb0ef41Sopenharmony_ci      }
3591cb0ef41Sopenharmony_ci      if (bodyConfig
3601cb0ef41Sopenharmony_ci              ->CreateDataProperty(context, toV8String(isolate, "groupName"),
3611cb0ef41Sopenharmony_ci                                   toV8String(isolate, groupName))
3621cb0ef41Sopenharmony_ci              .IsNothing()) {
3631cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
3641cb0ef41Sopenharmony_ci        return;
3651cb0ef41Sopenharmony_ci      }
3661cb0ef41Sopenharmony_ci      if (bodyConfig
3671cb0ef41Sopenharmony_ci              ->CreateDataProperty(context, toV8String(isolate, "config"),
3681cb0ef41Sopenharmony_ci                                   configValue)
3691cb0ef41Sopenharmony_ci              .IsNothing()) {
3701cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
3711cb0ef41Sopenharmony_ci        return;
3721cb0ef41Sopenharmony_ci      }
3731cb0ef41Sopenharmony_ci      if (bodyConfig
3741cb0ef41Sopenharmony_ci              ->CreateDataProperty(context, toV8String(isolate, "object"),
3751cb0ef41Sopenharmony_ci                                   object)
3761cb0ef41Sopenharmony_ci              .IsNothing()) {
3771cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
3781cb0ef41Sopenharmony_ci        return;
3791cb0ef41Sopenharmony_ci      }
3801cb0ef41Sopenharmony_ci      if (!v8::Function::New(context, bodyCallback, bodyConfig)
3811cb0ef41Sopenharmony_ci               .ToLocal(&bodyFunction)) {
3821cb0ef41Sopenharmony_ci        reportError(context, tryCatch);
3831cb0ef41Sopenharmony_ci        return;
3841cb0ef41Sopenharmony_ci      }
3851cb0ef41Sopenharmony_ci    }
3861cb0ef41Sopenharmony_ci    *preview = CustomPreview::create()
3871cb0ef41Sopenharmony_ci                   .setHeader(toProtocolString(isolate, header))
3881cb0ef41Sopenharmony_ci                   .build();
3891cb0ef41Sopenharmony_ci    if (!bodyFunction.IsEmpty()) {
3901cb0ef41Sopenharmony_ci      InjectedScript* injectedScript = getInjectedScript(context, sessionId);
3911cb0ef41Sopenharmony_ci      if (!injectedScript) {
3921cb0ef41Sopenharmony_ci        reportError(context, tryCatch, "cannot find context with specified id");
3931cb0ef41Sopenharmony_ci        return;
3941cb0ef41Sopenharmony_ci      }
3951cb0ef41Sopenharmony_ci      (*preview)->setBodyGetterId(
3961cb0ef41Sopenharmony_ci          injectedScript->bindObject(bodyFunction, groupName));
3971cb0ef41Sopenharmony_ci    }
3981cb0ef41Sopenharmony_ci    return;
3991cb0ef41Sopenharmony_ci  }
4001cb0ef41Sopenharmony_ci}
4011cb0ef41Sopenharmony_ci}  // namespace v8_inspector
402