14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "source_map.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include <cerrno>
194514f5e3Sopenharmony_ci#include <climits>
204514f5e3Sopenharmony_ci#include <cstdlib>
214514f5e3Sopenharmony_ci#include <fstream>
224514f5e3Sopenharmony_ci#include <vector>
234514f5e3Sopenharmony_ci#include <unistd.h>
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ci#include "ecmascript/base/string_helper.h"
264514f5e3Sopenharmony_ci#include "ecmascript/extractortool/src/extractor.h"
274514f5e3Sopenharmony_ci
284514f5e3Sopenharmony_cinamespace panda {
294514f5e3Sopenharmony_cinamespace ecmascript {
304514f5e3Sopenharmony_cinamespace {
314514f5e3Sopenharmony_cistatic constexpr char DELIMITER_COMMA = ',';
324514f5e3Sopenharmony_cistatic constexpr char DELIMITER_SEMICOLON = ';';
334514f5e3Sopenharmony_cistatic constexpr char DOUBLE_SLASH = '\\';
344514f5e3Sopenharmony_ci
354514f5e3Sopenharmony_cistatic constexpr int32_t INDEX_ONE = 1;
364514f5e3Sopenharmony_cistatic constexpr int32_t INDEX_TWO = 2;
374514f5e3Sopenharmony_cistatic constexpr int32_t INDEX_THREE = 3;
384514f5e3Sopenharmony_cistatic constexpr int32_t INDEX_FOUR = 4;
394514f5e3Sopenharmony_cistatic constexpr int32_t ANS_MAP_SIZE = 5;
404514f5e3Sopenharmony_cistatic constexpr int32_t DIGIT_NUM = 64;
414514f5e3Sopenharmony_ci
424514f5e3Sopenharmony_ciconst std::string MEGER_SOURCE_MAP_PATH = "ets/sourceMaps.map";
434514f5e3Sopenharmony_cistatic const CString FLAG_SOURCES = "    \"sources\":";
444514f5e3Sopenharmony_cistatic const CString FLAG_MAPPINGS = "    \"mappings\": \"";
454514f5e3Sopenharmony_cistatic const CString FLAG_END = "  }";
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_cistatic constexpr size_t FLAG_MAPPINGS_LEN = 17;
484514f5e3Sopenharmony_cistatic constexpr size_t REAL_SOURCE_SIZE = 7;
494514f5e3Sopenharmony_cistatic constexpr size_t REAL_URL_INDEX = 3;
504514f5e3Sopenharmony_cistatic constexpr size_t REAL_SOURCE_INDEX = 7;
514514f5e3Sopenharmony_ci} // namespace
524514f5e3Sopenharmony_ci
534514f5e3Sopenharmony_ci#if defined(PANDA_TARGET_OHOS)
544514f5e3Sopenharmony_cibool SourceMap::ReadSourceMapData(const std::string& hapPath, std::string& content)
554514f5e3Sopenharmony_ci{
564514f5e3Sopenharmony_ci    if (hapPath.empty()) {
574514f5e3Sopenharmony_ci        return false;
584514f5e3Sopenharmony_ci    }
594514f5e3Sopenharmony_ci    bool newCreate = false;
604514f5e3Sopenharmony_ci    std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(
614514f5e3Sopenharmony_ci        ExtractorUtil::GetLoadFilePath(hapPath), newCreate);
624514f5e3Sopenharmony_ci    if (extractor == nullptr) {
634514f5e3Sopenharmony_ci        return false;
644514f5e3Sopenharmony_ci    }
654514f5e3Sopenharmony_ci    std::unique_ptr<uint8_t[]> dataPtr = nullptr;
664514f5e3Sopenharmony_ci    size_t len = 0;
674514f5e3Sopenharmony_ci    if (!extractor->ExtractToBufByName(MEGER_SOURCE_MAP_PATH, dataPtr, len)) {
684514f5e3Sopenharmony_ci        return false;
694514f5e3Sopenharmony_ci    }
704514f5e3Sopenharmony_ci    content.assign(dataPtr.get(), dataPtr.get() + len);
714514f5e3Sopenharmony_ci    return true;
724514f5e3Sopenharmony_ci}
734514f5e3Sopenharmony_ci#endif
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ciuint32_t SourceMap::Base64CharToInt(char charCode)
764514f5e3Sopenharmony_ci{
774514f5e3Sopenharmony_ci    if ('A' <= charCode && charCode <= 'Z') {
784514f5e3Sopenharmony_ci        // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
794514f5e3Sopenharmony_ci        return charCode - 'A';
804514f5e3Sopenharmony_ci    } else if ('a' <= charCode && charCode <= 'z') {
814514f5e3Sopenharmony_ci        // 26 - 51: abcdefghijklmnopqrstuvwxyz
824514f5e3Sopenharmony_ci        return charCode - 'a' + 26;
834514f5e3Sopenharmony_ci    } else if ('0' <= charCode && charCode <= '9') {
844514f5e3Sopenharmony_ci        // 52 - 61: 0123456789
854514f5e3Sopenharmony_ci        return charCode - '0' + 52;
864514f5e3Sopenharmony_ci    } else if (charCode == '+') {
874514f5e3Sopenharmony_ci        // 62: +
884514f5e3Sopenharmony_ci        return 62;
894514f5e3Sopenharmony_ci    } else if (charCode == '/') {
904514f5e3Sopenharmony_ci        // 63: /
914514f5e3Sopenharmony_ci        return 63;
924514f5e3Sopenharmony_ci    }
934514f5e3Sopenharmony_ci    return DIGIT_NUM;
944514f5e3Sopenharmony_ci};
954514f5e3Sopenharmony_ci
964514f5e3Sopenharmony_ci#if defined(PANDA_TARGET_OHOS)
974514f5e3Sopenharmony_civoid SourceMap::Init(const std::string& hapPath)
984514f5e3Sopenharmony_ci{
994514f5e3Sopenharmony_ci    auto start = Clock::now();
1004514f5e3Sopenharmony_ci    std::string sourceMapData;
1014514f5e3Sopenharmony_ci    if (ReadSourceMapData(hapPath, sourceMapData)) {
1024514f5e3Sopenharmony_ci        SplitSourceMap(sourceMapData);
1034514f5e3Sopenharmony_ci    }
1044514f5e3Sopenharmony_ci    auto end = Clock::now();
1054514f5e3Sopenharmony_ci    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
1064514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "Init sourcemap time: " << duration.count() << "ms";
1074514f5e3Sopenharmony_ci}
1084514f5e3Sopenharmony_ci#endif
1094514f5e3Sopenharmony_ci
1104514f5e3Sopenharmony_civoid SourceMap::Init(uint8_t *data, size_t dataSize)
1114514f5e3Sopenharmony_ci{
1124514f5e3Sopenharmony_ci    std::string content;
1134514f5e3Sopenharmony_ci    content.assign(data, data + dataSize);
1144514f5e3Sopenharmony_ci    SplitSourceMap(content);
1154514f5e3Sopenharmony_ci}
1164514f5e3Sopenharmony_ci
1174514f5e3Sopenharmony_civoid SourceMap::SplitSourceMap(const std::string& sourceMapData)
1184514f5e3Sopenharmony_ci{
1194514f5e3Sopenharmony_ci    std::stringstream ss(sourceMapData);
1204514f5e3Sopenharmony_ci    std::string tmp;
1214514f5e3Sopenharmony_ci    std::string url;
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_ci    std::getline(ss, tmp);
1244514f5e3Sopenharmony_ci    bool isUrl = true;
1254514f5e3Sopenharmony_ci    while (std::getline(ss, tmp)) {
1264514f5e3Sopenharmony_ci        if (isUrl && tmp.size() > REAL_SOURCE_SIZE) {
1274514f5e3Sopenharmony_ci            url = tmp.substr(REAL_URL_INDEX, tmp.size() - REAL_SOURCE_SIZE);
1284514f5e3Sopenharmony_ci            isUrl = false;
1294514f5e3Sopenharmony_ci            continue;
1304514f5e3Sopenharmony_ci        }
1314514f5e3Sopenharmony_ci
1324514f5e3Sopenharmony_ci        if (base::StringHelper::StringStartWith(tmp.c_str(), FLAG_SOURCES)) {
1334514f5e3Sopenharmony_ci            std::getline(ss, tmp);
1344514f5e3Sopenharmony_ci            sources_.emplace(url, tmp);
1354514f5e3Sopenharmony_ci            continue;
1364514f5e3Sopenharmony_ci        }
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_ci        if (base::StringHelper::StringStartWith(tmp.c_str(), FLAG_MAPPINGS)) {
1394514f5e3Sopenharmony_ci            mappings_.emplace(url, tmp);
1404514f5e3Sopenharmony_ci            continue;
1414514f5e3Sopenharmony_ci        }
1424514f5e3Sopenharmony_ci
1434514f5e3Sopenharmony_ci        if (base::StringHelper::StringStartWith(tmp.c_str(), FLAG_END)) {
1444514f5e3Sopenharmony_ci            isUrl = true;
1454514f5e3Sopenharmony_ci        }
1464514f5e3Sopenharmony_ci    }
1474514f5e3Sopenharmony_ci}
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_civoid SourceMap::ExtractSourceMapData(const std::string& allmappings, std::shared_ptr<SourceMapData>& curMapData)
1504514f5e3Sopenharmony_ci{
1514514f5e3Sopenharmony_ci    curMapData->mappings_ = HandleMappings(allmappings);
1524514f5e3Sopenharmony_ci
1534514f5e3Sopenharmony_ci    // the first bit: the column after transferring.
1544514f5e3Sopenharmony_ci    // the second bit: the source file.
1554514f5e3Sopenharmony_ci    // the third bit: the row before transferring.
1564514f5e3Sopenharmony_ci    // the fourth bit: the column before transferring.
1574514f5e3Sopenharmony_ci    // the fifth bit: the variable name.
1584514f5e3Sopenharmony_ci    for (const auto& mapping : curMapData->mappings_) {
1594514f5e3Sopenharmony_ci        if (mapping == ";") {
1604514f5e3Sopenharmony_ci            // plus a line for each semicolon
1614514f5e3Sopenharmony_ci            curMapData->nowPos_.afterRow++,
1624514f5e3Sopenharmony_ci            curMapData->nowPos_.afterColumn = 0;
1634514f5e3Sopenharmony_ci            continue;
1644514f5e3Sopenharmony_ci        }
1654514f5e3Sopenharmony_ci        std::vector<int32_t> ans;
1664514f5e3Sopenharmony_ci
1674514f5e3Sopenharmony_ci        if (!VlqRevCode(mapping, ans)) {
1684514f5e3Sopenharmony_ci            return;
1694514f5e3Sopenharmony_ci        }
1704514f5e3Sopenharmony_ci        if (ans.empty()) {
1714514f5e3Sopenharmony_ci            break;
1724514f5e3Sopenharmony_ci        }
1734514f5e3Sopenharmony_ci        if (ans.size() == 1) {
1744514f5e3Sopenharmony_ci            curMapData->nowPos_.afterColumn += ans[0];
1754514f5e3Sopenharmony_ci            continue;
1764514f5e3Sopenharmony_ci        }
1774514f5e3Sopenharmony_ci        // after decode, assgin each value to the position
1784514f5e3Sopenharmony_ci        curMapData->nowPos_.afterColumn += ans[0];
1794514f5e3Sopenharmony_ci        curMapData->nowPos_.sourcesVal += ans[INDEX_ONE];
1804514f5e3Sopenharmony_ci        curMapData->nowPos_.beforeRow += ans[INDEX_TWO];
1814514f5e3Sopenharmony_ci        curMapData->nowPos_.beforeColumn += ans[INDEX_THREE];
1824514f5e3Sopenharmony_ci        if (ans.size() == ANS_MAP_SIZE) {
1834514f5e3Sopenharmony_ci            curMapData->nowPos_.namesVal += ans[INDEX_FOUR];
1844514f5e3Sopenharmony_ci        }
1854514f5e3Sopenharmony_ci        curMapData->afterPos_.push_back({
1864514f5e3Sopenharmony_ci            curMapData->nowPos_.beforeRow,
1874514f5e3Sopenharmony_ci            curMapData->nowPos_.beforeColumn,
1884514f5e3Sopenharmony_ci            curMapData->nowPos_.afterRow,
1894514f5e3Sopenharmony_ci            curMapData->nowPos_.afterColumn,
1904514f5e3Sopenharmony_ci            curMapData->nowPos_.sourcesVal,
1914514f5e3Sopenharmony_ci            curMapData->nowPos_.namesVal
1924514f5e3Sopenharmony_ci        });
1934514f5e3Sopenharmony_ci    }
1944514f5e3Sopenharmony_ci    curMapData->mappings_.clear();
1954514f5e3Sopenharmony_ci    curMapData->mappings_.shrink_to_fit();
1964514f5e3Sopenharmony_ci}
1974514f5e3Sopenharmony_ci
1984514f5e3Sopenharmony_ciMappingInfo SourceMap::Find(int32_t row, int32_t col, const SourceMapData& targetMap, bool& isReplaces)
1994514f5e3Sopenharmony_ci{
2004514f5e3Sopenharmony_ci    if (row < 1 || col < 1) {
2014514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "SourceMap find failed, line: " << row << ", column: " << col;
2024514f5e3Sopenharmony_ci        return MappingInfo { 0, 0 };
2034514f5e3Sopenharmony_ci    } else if (targetMap.afterPos_.empty()) {
2044514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Target map can't find after pos.";
2054514f5e3Sopenharmony_ci        return MappingInfo { 0, 0 };
2064514f5e3Sopenharmony_ci    }
2074514f5e3Sopenharmony_ci    row--;
2084514f5e3Sopenharmony_ci    col--;
2094514f5e3Sopenharmony_ci    // binary search
2104514f5e3Sopenharmony_ci    int32_t left = 0;
2114514f5e3Sopenharmony_ci    int32_t right = static_cast<int32_t>(targetMap.afterPos_.size()) - 1;
2124514f5e3Sopenharmony_ci    int32_t res = 0;
2134514f5e3Sopenharmony_ci    if (row > targetMap.afterPos_[targetMap.afterPos_.size() - 1].afterRow) {
2144514f5e3Sopenharmony_ci        isReplaces = false;
2154514f5e3Sopenharmony_ci        return MappingInfo { row + 1, col + 1};
2164514f5e3Sopenharmony_ci    }
2174514f5e3Sopenharmony_ci    while (right - left >= 0) {
2184514f5e3Sopenharmony_ci        int32_t mid = (right + left) / 2;
2194514f5e3Sopenharmony_ci        if ((targetMap.afterPos_[mid].afterRow == row && targetMap.afterPos_[mid].afterColumn > col) ||
2204514f5e3Sopenharmony_ci             targetMap.afterPos_[mid].afterRow > row) {
2214514f5e3Sopenharmony_ci            right = mid - 1;
2224514f5e3Sopenharmony_ci        } else {
2234514f5e3Sopenharmony_ci            res = mid;
2244514f5e3Sopenharmony_ci            left = mid + 1;
2254514f5e3Sopenharmony_ci        }
2264514f5e3Sopenharmony_ci    }
2274514f5e3Sopenharmony_ci    return MappingInfo { targetMap.afterPos_[res].beforeRow + 1, targetMap.afterPos_[res].beforeColumn + 1 };
2284514f5e3Sopenharmony_ci}
2294514f5e3Sopenharmony_ci
2304514f5e3Sopenharmony_civoid SourceMap::ExtractKeyInfo(const std::string& sourceMap, std::vector<std::string>& sourceKeyInfo)
2314514f5e3Sopenharmony_ci{
2324514f5e3Sopenharmony_ci    uint32_t cnt = 0;
2334514f5e3Sopenharmony_ci    std::string tempStr;
2344514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < sourceMap.size(); i++) {
2354514f5e3Sopenharmony_ci        // reslove json file
2364514f5e3Sopenharmony_ci        if (sourceMap[i] == DOUBLE_SLASH) {
2374514f5e3Sopenharmony_ci            i++;
2384514f5e3Sopenharmony_ci            tempStr += sourceMap[i];
2394514f5e3Sopenharmony_ci            continue;
2404514f5e3Sopenharmony_ci        }
2414514f5e3Sopenharmony_ci        // cnt is used to represent a pair of double quotation marks: ""
2424514f5e3Sopenharmony_ci        if (sourceMap[i] == '"') {
2434514f5e3Sopenharmony_ci            cnt++;
2444514f5e3Sopenharmony_ci        }
2454514f5e3Sopenharmony_ci        if (cnt == INDEX_TWO) {
2464514f5e3Sopenharmony_ci            sourceKeyInfo.push_back(tempStr);
2474514f5e3Sopenharmony_ci            tempStr = "";
2484514f5e3Sopenharmony_ci            cnt = 0;
2494514f5e3Sopenharmony_ci        } else if (cnt == 1) {
2504514f5e3Sopenharmony_ci            if (sourceMap[i] != '"') {
2514514f5e3Sopenharmony_ci                tempStr += sourceMap[i];
2524514f5e3Sopenharmony_ci            }
2534514f5e3Sopenharmony_ci        }
2544514f5e3Sopenharmony_ci    }
2554514f5e3Sopenharmony_ci}
2564514f5e3Sopenharmony_ci
2574514f5e3Sopenharmony_civoid SourceMap::GetPosInfo(const std::string& temp, int32_t start, std::string& line, std::string& column)
2584514f5e3Sopenharmony_ci{
2594514f5e3Sopenharmony_ci    // 0 for colum, 1 for row
2604514f5e3Sopenharmony_ci    int32_t flag = 0;
2614514f5e3Sopenharmony_ci    // find line, column
2624514f5e3Sopenharmony_ci    for (int32_t i = start - 1; i > 0; i--) {
2634514f5e3Sopenharmony_ci        if (temp[i] == ':') {
2644514f5e3Sopenharmony_ci            flag += 1;
2654514f5e3Sopenharmony_ci            continue;
2664514f5e3Sopenharmony_ci        }
2674514f5e3Sopenharmony_ci        if (flag == 0) {
2684514f5e3Sopenharmony_ci            column = temp[i] + column;
2694514f5e3Sopenharmony_ci        } else if (flag == 1) {
2704514f5e3Sopenharmony_ci            line = temp[i] + line;
2714514f5e3Sopenharmony_ci        } else {
2724514f5e3Sopenharmony_ci            break;
2734514f5e3Sopenharmony_ci        }
2744514f5e3Sopenharmony_ci    }
2754514f5e3Sopenharmony_ci}
2764514f5e3Sopenharmony_ci
2774514f5e3Sopenharmony_cistd::vector<std::string> SourceMap::HandleMappings(const std::string& mapping)
2784514f5e3Sopenharmony_ci{
2794514f5e3Sopenharmony_ci    std::vector<std::string> keyInfo;
2804514f5e3Sopenharmony_ci    std::string tempStr;
2814514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < mapping.size(); i++) {
2824514f5e3Sopenharmony_ci        if (mapping[i] == DELIMITER_COMMA) {
2834514f5e3Sopenharmony_ci            keyInfo.push_back(tempStr);
2844514f5e3Sopenharmony_ci            tempStr = "";
2854514f5e3Sopenharmony_ci        } else if (mapping[i] == DELIMITER_SEMICOLON) {
2864514f5e3Sopenharmony_ci            if (tempStr != "") {
2874514f5e3Sopenharmony_ci                keyInfo.push_back(tempStr);
2884514f5e3Sopenharmony_ci            }
2894514f5e3Sopenharmony_ci            tempStr = "";
2904514f5e3Sopenharmony_ci            keyInfo.push_back(";");
2914514f5e3Sopenharmony_ci        } else {
2924514f5e3Sopenharmony_ci            tempStr += mapping[i];
2934514f5e3Sopenharmony_ci        }
2944514f5e3Sopenharmony_ci    }
2954514f5e3Sopenharmony_ci    if (tempStr != "") {
2964514f5e3Sopenharmony_ci        keyInfo.push_back(tempStr);
2974514f5e3Sopenharmony_ci    }
2984514f5e3Sopenharmony_ci    return keyInfo;
2994514f5e3Sopenharmony_ci};
3004514f5e3Sopenharmony_ci
3014514f5e3Sopenharmony_cibool SourceMap::VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans)
3024514f5e3Sopenharmony_ci{
3034514f5e3Sopenharmony_ci    const int32_t VLQ_BASE_SHIFT = 5;
3044514f5e3Sopenharmony_ci    // binary: 100000
3054514f5e3Sopenharmony_ci    uint32_t VLQ_BASE = 1 << VLQ_BASE_SHIFT;
3064514f5e3Sopenharmony_ci    // binary: 011111
3074514f5e3Sopenharmony_ci    uint32_t VLQ_BASE_MASK = VLQ_BASE - 1;
3084514f5e3Sopenharmony_ci    // binary: 100000
3094514f5e3Sopenharmony_ci    uint32_t VLQ_CONTINUATION_BIT = VLQ_BASE;
3104514f5e3Sopenharmony_ci    uint32_t result = 0;
3114514f5e3Sopenharmony_ci    uint32_t shift = 0;
3124514f5e3Sopenharmony_ci    bool continuation = 0;
3134514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < vStr.size(); i++) {
3144514f5e3Sopenharmony_ci        uint32_t digit = Base64CharToInt(vStr[i]);
3154514f5e3Sopenharmony_ci        if (digit == DIGIT_NUM) {
3164514f5e3Sopenharmony_ci            return false;
3174514f5e3Sopenharmony_ci        }
3184514f5e3Sopenharmony_ci        continuation = digit & VLQ_CONTINUATION_BIT;
3194514f5e3Sopenharmony_ci        digit &= VLQ_BASE_MASK;
3204514f5e3Sopenharmony_ci        result += digit << shift;
3214514f5e3Sopenharmony_ci        if (continuation) {
3224514f5e3Sopenharmony_ci            shift += VLQ_BASE_SHIFT;
3234514f5e3Sopenharmony_ci        } else {
3244514f5e3Sopenharmony_ci            bool isNegate = result & 1;
3254514f5e3Sopenharmony_ci            result >>= 1;
3264514f5e3Sopenharmony_ci            ans.push_back(isNegate ? -result : result);
3274514f5e3Sopenharmony_ci            result = 0;
3284514f5e3Sopenharmony_ci            shift = 0;
3294514f5e3Sopenharmony_ci        }
3304514f5e3Sopenharmony_ci    }
3314514f5e3Sopenharmony_ci    if (continuation) {
3324514f5e3Sopenharmony_ci        return false;
3334514f5e3Sopenharmony_ci    }
3344514f5e3Sopenharmony_ci    return true;
3354514f5e3Sopenharmony_ci};
3364514f5e3Sopenharmony_ci
3374514f5e3Sopenharmony_cibool SourceMap::TranslateUrlPositionBySourceMap(std::string& url, int& line, int& column)
3384514f5e3Sopenharmony_ci{
3394514f5e3Sopenharmony_ci    std::string tmp = sources_[url];
3404514f5e3Sopenharmony_ci    if (tmp.empty() || tmp.size() < REAL_SOURCE_SIZE + 1) {
3414514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Translate failed, url: " << url;
3424514f5e3Sopenharmony_ci        return false;
3434514f5e3Sopenharmony_ci    }
3444514f5e3Sopenharmony_ci    tmp = tmp.substr(REAL_SOURCE_INDEX, tmp.size() - REAL_SOURCE_SIZE - 1);
3454514f5e3Sopenharmony_ci    if (url.rfind(".js") != std::string::npos) {
3464514f5e3Sopenharmony_ci        url = tmp;
3474514f5e3Sopenharmony_ci        return true;
3484514f5e3Sopenharmony_ci    }
3494514f5e3Sopenharmony_ci    bool isReplaces = true;
3504514f5e3Sopenharmony_ci    bool ret = false;
3514514f5e3Sopenharmony_ci    auto iterData = sourceMaps_.find(url);
3524514f5e3Sopenharmony_ci    if (iterData != sourceMaps_.end()) {
3534514f5e3Sopenharmony_ci        if (iterData->second == nullptr) {
3544514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "Extract mappings failed, url: " << url;
3554514f5e3Sopenharmony_ci            return false;
3564514f5e3Sopenharmony_ci        }
3574514f5e3Sopenharmony_ci        ret = GetLineAndColumnNumbers(line, column, *(iterData->second), isReplaces);
3584514f5e3Sopenharmony_ci        if (isReplaces) {
3594514f5e3Sopenharmony_ci            url = tmp;
3604514f5e3Sopenharmony_ci        }
3614514f5e3Sopenharmony_ci        return ret;
3624514f5e3Sopenharmony_ci    }
3634514f5e3Sopenharmony_ci    auto iter = mappings_.find(url);
3644514f5e3Sopenharmony_ci    if (iter != mappings_.end()) {
3654514f5e3Sopenharmony_ci        std::string mappings = mappings_[url];
3664514f5e3Sopenharmony_ci        if (mappings.size() < FLAG_MAPPINGS_LEN + 1) {
3674514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "Translate failed, url: " << url << ", mappings: " << mappings;
3684514f5e3Sopenharmony_ci            return false;
3694514f5e3Sopenharmony_ci        }
3704514f5e3Sopenharmony_ci        std::shared_ptr<SourceMapData> modularMap = std::make_shared<SourceMapData>();
3714514f5e3Sopenharmony_ci        if (modularMap == nullptr) {
3724514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "New SourceMapData failed";
3734514f5e3Sopenharmony_ci            return false;
3744514f5e3Sopenharmony_ci        }
3754514f5e3Sopenharmony_ci        ExtractSourceMapData(mappings.substr(FLAG_MAPPINGS_LEN, mappings.size() - FLAG_MAPPINGS_LEN - 1), modularMap);
3764514f5e3Sopenharmony_ci        sourceMaps_.emplace(url, modularMap);
3774514f5e3Sopenharmony_ci        ret = GetLineAndColumnNumbers(line, column, *(modularMap), isReplaces);
3784514f5e3Sopenharmony_ci        if (isReplaces) {
3794514f5e3Sopenharmony_ci            url = tmp;
3804514f5e3Sopenharmony_ci        }
3814514f5e3Sopenharmony_ci        return ret;
3824514f5e3Sopenharmony_ci    }
3834514f5e3Sopenharmony_ci    return false;
3844514f5e3Sopenharmony_ci}
3854514f5e3Sopenharmony_ci
3864514f5e3Sopenharmony_cibool SourceMap::GetLineAndColumnNumbers(int& line, int& column, SourceMapData& targetMap, bool& isReplaces)
3874514f5e3Sopenharmony_ci{
3884514f5e3Sopenharmony_ci    int32_t offSet = 0;
3894514f5e3Sopenharmony_ci    MappingInfo mapInfo;
3904514f5e3Sopenharmony_ci#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
3914514f5e3Sopenharmony_ci    mapInfo = Find(line - offSet + OFFSET_PREVIEW, column, targetMap, isReplaces);
3924514f5e3Sopenharmony_ci#else
3934514f5e3Sopenharmony_ci    mapInfo = Find(line - offSet, column, targetMap, isReplaces);
3944514f5e3Sopenharmony_ci#endif
3954514f5e3Sopenharmony_ci    if (mapInfo.row == 0 || mapInfo.col == 0) {
3964514f5e3Sopenharmony_ci        return false;
3974514f5e3Sopenharmony_ci    } else {
3984514f5e3Sopenharmony_ci        line = mapInfo.row;
3994514f5e3Sopenharmony_ci        column = mapInfo.col;
4004514f5e3Sopenharmony_ci        return true;
4014514f5e3Sopenharmony_ci    }
4024514f5e3Sopenharmony_ci}
4034514f5e3Sopenharmony_ci}   // namespace panda
4044514f5e3Sopenharmony_ci}   // namespace ecmascript
405