13920e296Sopenharmony_ci/*
23920e296Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
33920e296Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43920e296Sopenharmony_ci * you may not use this file except in compliance with the License.
53920e296Sopenharmony_ci * You may obtain a copy of the License at
63920e296Sopenharmony_ci *
73920e296Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83920e296Sopenharmony_ci *
93920e296Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103920e296Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113920e296Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123920e296Sopenharmony_ci * See the License for the specific language governing permissions and
133920e296Sopenharmony_ci * limitations under the License.
143920e296Sopenharmony_ci */
153920e296Sopenharmony_ci
163920e296Sopenharmony_ci#include "config_parser.h"
173920e296Sopenharmony_ci#include <iostream>
183920e296Sopenharmony_ci#include <regex>
193920e296Sopenharmony_ci#include "reference_parser.h"
203920e296Sopenharmony_ci#include "restool_errors.h"
213920e296Sopenharmony_ci
223920e296Sopenharmony_cinamespace OHOS {
233920e296Sopenharmony_cinamespace Global {
243920e296Sopenharmony_cinamespace Restool {
253920e296Sopenharmony_ciusing namespace std;
263920e296Sopenharmony_ciconst map<string, ConfigParser::ModuleType> ConfigParser::MODULE_TYPES = {
273920e296Sopenharmony_ci    { "har", ModuleType::HAR },
283920e296Sopenharmony_ci    { "entry", ModuleType::ENTRY },
293920e296Sopenharmony_ci    { "feature", ModuleType::FEATURE },
303920e296Sopenharmony_ci    { "shared", ModuleType::SHARED }
313920e296Sopenharmony_ci};
323920e296Sopenharmony_ci
333920e296Sopenharmony_ciconst map<string, string> ConfigParser::JSON_STRING_IDS = {
343920e296Sopenharmony_ci    { "icon", "^\\$media:" },
353920e296Sopenharmony_ci    { "label", "^\\$string:" },
363920e296Sopenharmony_ci    { "description", "^\\$string:" },
373920e296Sopenharmony_ci    { "theme", "^\\$theme:" },
383920e296Sopenharmony_ci    { "reason", "^\\$string:" },
393920e296Sopenharmony_ci    { "startWindowIcon", "^\\$media:" },
403920e296Sopenharmony_ci    { "startWindowBackground", "^\\$color:"},
413920e296Sopenharmony_ci    { "resource", "^\\$[a-z]+:" },
423920e296Sopenharmony_ci    { "extra", "^\\$[a-z]+:" },
433920e296Sopenharmony_ci    { "fileContextMenu", "^\\$profile:" },
443920e296Sopenharmony_ci    { "orientation", "^\\$string:" }
453920e296Sopenharmony_ci};
463920e296Sopenharmony_ci
473920e296Sopenharmony_ciconst map<string, string> ConfigParser::JSON_ARRAY_IDS = {
483920e296Sopenharmony_ci    { "landscapeLayouts", "^\\$layout:" },
493920e296Sopenharmony_ci    { "portraitLayouts", "^\\$layout:" }
503920e296Sopenharmony_ci};
513920e296Sopenharmony_ci
523920e296Sopenharmony_cibool ConfigParser::useModule_ = false;
533920e296Sopenharmony_ci
543920e296Sopenharmony_ciConfigParser::ConfigParser()
553920e296Sopenharmony_ci    : filePath_(""), packageName_(""), moduleName_(""), moduleType_(ModuleType::NONE),
563920e296Sopenharmony_ci    abilityIconId_(0), abilityLabelId_(0), root_(nullptr)
573920e296Sopenharmony_ci{
583920e296Sopenharmony_ci}
593920e296Sopenharmony_ci
603920e296Sopenharmony_ciConfigParser::ConfigParser(const string &filePath)
613920e296Sopenharmony_ci    : filePath_(filePath), packageName_(""), moduleName_(""), moduleType_(ModuleType::NONE),
623920e296Sopenharmony_ci    abilityIconId_(0), abilityLabelId_(0), root_(nullptr)
633920e296Sopenharmony_ci{
643920e296Sopenharmony_ci}
653920e296Sopenharmony_ci
663920e296Sopenharmony_ciConfigParser::~ConfigParser()
673920e296Sopenharmony_ci{
683920e296Sopenharmony_ci    if (root_) {
693920e296Sopenharmony_ci        cJSON_Delete(root_);
703920e296Sopenharmony_ci    }
713920e296Sopenharmony_ci}
723920e296Sopenharmony_ci
733920e296Sopenharmony_ciuint32_t ConfigParser::Init()
743920e296Sopenharmony_ci{
753920e296Sopenharmony_ci    if (!ResourceUtil::OpenJsonFile(filePath_, &root_)) {
763920e296Sopenharmony_ci        return RESTOOL_ERROR;
773920e296Sopenharmony_ci    }
783920e296Sopenharmony_ci
793920e296Sopenharmony_ci    if (!root_ || !cJSON_IsObject(root_)) {
803920e296Sopenharmony_ci        cerr << "Error: JSON file parsing failed, please check the JSON file." << NEW_LINE_PATH << filePath_ << endl;
813920e296Sopenharmony_ci        return RESTOOL_ERROR;
823920e296Sopenharmony_ci    }
833920e296Sopenharmony_ci
843920e296Sopenharmony_ci    cJSON *moduleNode = cJSON_GetObjectItem(root_, "module");
853920e296Sopenharmony_ci    if (!ParseModule(moduleNode)) {
863920e296Sopenharmony_ci        return RESTOOL_ERROR;
873920e296Sopenharmony_ci    }
883920e296Sopenharmony_ci    return RESTOOL_SUCCESS;
893920e296Sopenharmony_ci}
903920e296Sopenharmony_ci
913920e296Sopenharmony_ciconst string &ConfigParser::GetPackageName() const
923920e296Sopenharmony_ci{
933920e296Sopenharmony_ci    return packageName_;
943920e296Sopenharmony_ci}
953920e296Sopenharmony_ci
963920e296Sopenharmony_ciconst string &ConfigParser::GetModuleName() const
973920e296Sopenharmony_ci{
983920e296Sopenharmony_ci    return moduleName_;
993920e296Sopenharmony_ci}
1003920e296Sopenharmony_ci
1013920e296Sopenharmony_ciint64_t ConfigParser::GetAbilityIconId() const
1023920e296Sopenharmony_ci{
1033920e296Sopenharmony_ci    return abilityIconId_;
1043920e296Sopenharmony_ci}
1053920e296Sopenharmony_ci
1063920e296Sopenharmony_ciint64_t ConfigParser::GetAbilityLabelId() const
1073920e296Sopenharmony_ci{
1083920e296Sopenharmony_ci    return abilityLabelId_;
1093920e296Sopenharmony_ci}
1103920e296Sopenharmony_ci
1113920e296Sopenharmony_ciConfigParser::ModuleType ConfigParser::GetModuleType() const
1123920e296Sopenharmony_ci{
1133920e296Sopenharmony_ci    return moduleType_;
1143920e296Sopenharmony_ci}
1153920e296Sopenharmony_ci
1163920e296Sopenharmony_ciuint32_t ConfigParser::ParseRefence()
1173920e296Sopenharmony_ci{
1183920e296Sopenharmony_ci    if (ParseRefImpl(root_, "", root_)) {
1193920e296Sopenharmony_ci        return RESTOOL_SUCCESS;
1203920e296Sopenharmony_ci    }
1213920e296Sopenharmony_ci    return RESTOOL_ERROR;
1223920e296Sopenharmony_ci}
1233920e296Sopenharmony_ci
1243920e296Sopenharmony_ciuint32_t ConfigParser::Save(const string &filePath) const
1253920e296Sopenharmony_ci{
1263920e296Sopenharmony_ci    if (ResourceUtil::SaveToJsonFile(filePath, root_)) {
1273920e296Sopenharmony_ci        return RESTOOL_SUCCESS;
1283920e296Sopenharmony_ci    }
1293920e296Sopenharmony_ci    return RESTOOL_ERROR;
1303920e296Sopenharmony_ci}
1313920e296Sopenharmony_ci
1323920e296Sopenharmony_cibool ConfigParser::SetAppIcon(string &icon, int64_t id)
1333920e296Sopenharmony_ci{
1343920e296Sopenharmony_ci    cJSON *appNode = cJSON_GetObjectItem(root_, "app");
1353920e296Sopenharmony_ci    if (!appNode || !cJSON_IsObject(appNode)) {
1363920e296Sopenharmony_ci        cerr << "Error: 'app' not object" << endl;
1373920e296Sopenharmony_ci        return false;
1383920e296Sopenharmony_ci    }
1393920e296Sopenharmony_ci    cJSON_AddStringToObject(appNode, "icon", icon.c_str());
1403920e296Sopenharmony_ci    cJSON_AddNumberToObject(appNode, "iconId", id);
1413920e296Sopenharmony_ci    return true;
1423920e296Sopenharmony_ci}
1433920e296Sopenharmony_ci
1443920e296Sopenharmony_cibool ConfigParser::SetAppLabel(string &label, int64_t id)
1453920e296Sopenharmony_ci{
1463920e296Sopenharmony_ci    cJSON *appNode = cJSON_GetObjectItem(root_, "app");
1473920e296Sopenharmony_ci    if (!appNode || !cJSON_IsObject(appNode)) {
1483920e296Sopenharmony_ci        cerr << "Error: 'app' not object" << endl;
1493920e296Sopenharmony_ci        return false;
1503920e296Sopenharmony_ci    }
1513920e296Sopenharmony_ci    cJSON_AddStringToObject(appNode, "label", label.c_str());
1523920e296Sopenharmony_ci    cJSON_AddNumberToObject(appNode, "labelId", id);
1533920e296Sopenharmony_ci    return true;
1543920e296Sopenharmony_ci}
1553920e296Sopenharmony_ci
1563920e296Sopenharmony_ci// below private
1573920e296Sopenharmony_cibool ConfigParser::ParseModule(cJSON *moduleNode)
1583920e296Sopenharmony_ci{
1593920e296Sopenharmony_ci    if (!moduleNode || !cJSON_IsObject(moduleNode)) {
1603920e296Sopenharmony_ci        cerr << "Error: 'module' not object." << NEW_LINE_PATH << filePath_ << endl;
1613920e296Sopenharmony_ci        return false;
1623920e296Sopenharmony_ci    }
1633920e296Sopenharmony_ci    if (cJSON_GetArraySize(moduleNode) == 0) {
1643920e296Sopenharmony_ci        cerr << "Error: 'module' empty." << NEW_LINE_PATH << filePath_ << endl;
1653920e296Sopenharmony_ci        return false;
1663920e296Sopenharmony_ci    }
1673920e296Sopenharmony_ci
1683920e296Sopenharmony_ci    if (!useModule_) {
1693920e296Sopenharmony_ci        cJSON *packageNode = cJSON_GetObjectItem(moduleNode, "package");
1703920e296Sopenharmony_ci        if (packageNode && cJSON_IsString(packageNode)) {
1713920e296Sopenharmony_ci            packageName_ = packageNode->valuestring;
1723920e296Sopenharmony_ci        }
1733920e296Sopenharmony_ci        cJSON *distroNode = cJSON_GetObjectItem(moduleNode, "distro");
1743920e296Sopenharmony_ci        if (!ParseDistro(distroNode)) {
1753920e296Sopenharmony_ci            return false;
1763920e296Sopenharmony_ci        }
1773920e296Sopenharmony_ci        return ParseAbilitiesForDepend(moduleNode);
1783920e296Sopenharmony_ci    }
1793920e296Sopenharmony_ci    cJSON *nameNode = cJSON_GetObjectItem(moduleNode, "name");
1803920e296Sopenharmony_ci    if (nameNode && cJSON_IsString(nameNode)) {
1813920e296Sopenharmony_ci        moduleName_ = nameNode->valuestring;
1823920e296Sopenharmony_ci    }
1833920e296Sopenharmony_ci
1843920e296Sopenharmony_ci    if (moduleName_.empty()) {
1853920e296Sopenharmony_ci        cerr << "Error: 'name' don't found in 'module'." << NEW_LINE_PATH << filePath_ << endl;
1863920e296Sopenharmony_ci        return false;
1873920e296Sopenharmony_ci    }
1883920e296Sopenharmony_ci    cJSON *typeNode = cJSON_GetObjectItem(moduleNode, "type");
1893920e296Sopenharmony_ci    if (typeNode && cJSON_IsString(typeNode) && !ParseModuleType(typeNode->valuestring)) {
1903920e296Sopenharmony_ci        return false;
1913920e296Sopenharmony_ci    }
1923920e296Sopenharmony_ci    return true;
1933920e296Sopenharmony_ci}
1943920e296Sopenharmony_ci
1953920e296Sopenharmony_cibool ConfigParser::ParseAbilitiesForDepend(cJSON *moduleNode)
1963920e296Sopenharmony_ci{
1973920e296Sopenharmony_ci    if (!IsDependEntry()) {
1983920e296Sopenharmony_ci        return true;
1993920e296Sopenharmony_ci    }
2003920e296Sopenharmony_ci    cJSON *mainAbilityNode = cJSON_GetObjectItem(moduleNode, "mainAbility");
2013920e296Sopenharmony_ci    if (mainAbilityNode && cJSON_IsString(mainAbilityNode)) {
2023920e296Sopenharmony_ci        mainAbility_ = mainAbilityNode->valuestring;
2033920e296Sopenharmony_ci        if (mainAbility_[0] == '.') {
2043920e296Sopenharmony_ci            mainAbility_ = packageName_ + mainAbility_;
2053920e296Sopenharmony_ci        }
2063920e296Sopenharmony_ci        return ParseAbilities(cJSON_GetObjectItem(moduleNode, "abilities"));
2073920e296Sopenharmony_ci    }
2083920e296Sopenharmony_ci    return true;
2093920e296Sopenharmony_ci}
2103920e296Sopenharmony_ci
2113920e296Sopenharmony_cibool ConfigParser::ParseDistro(cJSON *distroNode)
2123920e296Sopenharmony_ci{
2133920e296Sopenharmony_ci    if (!distroNode || !cJSON_IsObject(distroNode)) {
2143920e296Sopenharmony_ci        cerr << "Error: 'distro' not object." << NEW_LINE_PATH << filePath_ << endl;
2153920e296Sopenharmony_ci        return false;
2163920e296Sopenharmony_ci    }
2173920e296Sopenharmony_ci    if (cJSON_GetArraySize(distroNode) == 0) {
2183920e296Sopenharmony_ci        cerr << "Error: 'distro' empty." << NEW_LINE_PATH << filePath_ << endl;
2193920e296Sopenharmony_ci        return false;
2203920e296Sopenharmony_ci    }
2213920e296Sopenharmony_ci
2223920e296Sopenharmony_ci    cJSON *moduleNameNode = cJSON_GetObjectItem(distroNode, "moduleName");
2233920e296Sopenharmony_ci    if (moduleNameNode && cJSON_IsString(moduleNameNode)) {
2243920e296Sopenharmony_ci        moduleName_ = moduleNameNode->valuestring;
2253920e296Sopenharmony_ci    }
2263920e296Sopenharmony_ci
2273920e296Sopenharmony_ci    if (moduleName_.empty()) {
2283920e296Sopenharmony_ci        cerr << "Error: 'moduleName' don't found in 'distro'." << NEW_LINE_PATH << filePath_ << endl;
2293920e296Sopenharmony_ci        return false;
2303920e296Sopenharmony_ci    }
2313920e296Sopenharmony_ci
2323920e296Sopenharmony_ci    cJSON *moduleTypeNode = cJSON_GetObjectItem(distroNode, "moduleType");
2333920e296Sopenharmony_ci    if (moduleTypeNode && cJSON_IsString(moduleTypeNode) && !ParseModuleType(moduleTypeNode->valuestring)) {
2343920e296Sopenharmony_ci        return false;
2353920e296Sopenharmony_ci    }
2363920e296Sopenharmony_ci    return true;
2373920e296Sopenharmony_ci}
2383920e296Sopenharmony_ci
2393920e296Sopenharmony_cibool ConfigParser::ParseAbilities(const cJSON *abilities)
2403920e296Sopenharmony_ci{
2413920e296Sopenharmony_ci    if (!abilities || !cJSON_IsArray(abilities)) {
2423920e296Sopenharmony_ci        cerr << "Error: abilites not array." << NEW_LINE_PATH << filePath_ << endl;
2433920e296Sopenharmony_ci        return false;
2443920e296Sopenharmony_ci    }
2453920e296Sopenharmony_ci    if (cJSON_GetArraySize(abilities) == 0) {
2463920e296Sopenharmony_ci        return true;
2473920e296Sopenharmony_ci    }
2483920e296Sopenharmony_ci    bool isMainAbility = false;
2493920e296Sopenharmony_ci    for (cJSON *ability = abilities->child; ability; ability = ability->next) {
2503920e296Sopenharmony_ci        if (!ParseAbilitiy(ability, isMainAbility)) {
2513920e296Sopenharmony_ci            cerr << "Error: ParseAbilitiy fail." << endl;
2523920e296Sopenharmony_ci            return false;
2533920e296Sopenharmony_ci        }
2543920e296Sopenharmony_ci        if (isMainAbility) {
2553920e296Sopenharmony_ci            break;
2563920e296Sopenharmony_ci        }
2573920e296Sopenharmony_ci    }
2583920e296Sopenharmony_ci    return true;
2593920e296Sopenharmony_ci}
2603920e296Sopenharmony_ci
2613920e296Sopenharmony_cibool ConfigParser::ParseAbilitiy(const cJSON *ability, bool &isMainAbility)
2623920e296Sopenharmony_ci{
2633920e296Sopenharmony_ci    if (!ability || !cJSON_IsObject(ability)) {
2643920e296Sopenharmony_ci        cerr << "Error: ability not object." << NEW_LINE_PATH << filePath_ << endl;
2653920e296Sopenharmony_ci        return false;
2663920e296Sopenharmony_ci    }
2673920e296Sopenharmony_ci    if (cJSON_GetArraySize(ability) == 0) {
2683920e296Sopenharmony_ci        return true;
2693920e296Sopenharmony_ci    }
2703920e296Sopenharmony_ci    cJSON *nameNode = cJSON_GetObjectItem(ability, "name");
2713920e296Sopenharmony_ci    if (!nameNode || !cJSON_IsString(nameNode)) {
2723920e296Sopenharmony_ci        return false;
2733920e296Sopenharmony_ci    }
2743920e296Sopenharmony_ci    string name = nameNode->valuestring;
2753920e296Sopenharmony_ci    if (name[0] == '.') {
2763920e296Sopenharmony_ci        name = packageName_ + name;
2773920e296Sopenharmony_ci    }
2783920e296Sopenharmony_ci    if (mainAbility_ != name && !IsMainAbility(cJSON_GetObjectItem(ability, "skills"))) {
2793920e296Sopenharmony_ci        return true;
2803920e296Sopenharmony_ci    }
2813920e296Sopenharmony_ci    cJSON *iconIdNode = cJSON_GetObjectItem(ability, "iconId");
2823920e296Sopenharmony_ci    if (iconIdNode && ResourceUtil::IsIntValue(iconIdNode)) {
2833920e296Sopenharmony_ci        abilityIconId_ = iconIdNode->valueint;
2843920e296Sopenharmony_ci    }
2853920e296Sopenharmony_ci    if (abilityIconId_ <= 0) {
2863920e296Sopenharmony_ci        cerr << "Error: iconId don't found in 'ability'." << NEW_LINE_PATH << filePath_ << endl;
2873920e296Sopenharmony_ci        return false;
2883920e296Sopenharmony_ci    }
2893920e296Sopenharmony_ci    cJSON *labelIdNode = cJSON_GetObjectItem(ability, "labelId");
2903920e296Sopenharmony_ci    if (labelIdNode && ResourceUtil::IsIntValue(labelIdNode)) {
2913920e296Sopenharmony_ci        abilityLabelId_ = labelIdNode->valueint;
2923920e296Sopenharmony_ci    }
2933920e296Sopenharmony_ci    if (abilityLabelId_ <= 0) {
2943920e296Sopenharmony_ci        cerr << "Error: labelId don't found in 'ability'." << NEW_LINE_PATH << filePath_ << endl;
2953920e296Sopenharmony_ci        return false;
2963920e296Sopenharmony_ci    }
2973920e296Sopenharmony_ci    isMainAbility = true;
2983920e296Sopenharmony_ci    return true;
2993920e296Sopenharmony_ci}
3003920e296Sopenharmony_ci
3013920e296Sopenharmony_cibool ConfigParser::IsMainAbility(const cJSON *skills)
3023920e296Sopenharmony_ci{
3033920e296Sopenharmony_ci    if (!skills || !cJSON_IsArray(skills)) {
3043920e296Sopenharmony_ci        return false;
3053920e296Sopenharmony_ci    }
3063920e296Sopenharmony_ci    for (cJSON *skill = skills->child; skill; skill = skill->next) {
3073920e296Sopenharmony_ci        if (!cJSON_IsObject(skill)) {
3083920e296Sopenharmony_ci            return false;
3093920e296Sopenharmony_ci        }
3103920e296Sopenharmony_ci        if (IsHomeAction(cJSON_GetObjectItem(skill, "actions"))) {
3113920e296Sopenharmony_ci            return true;
3123920e296Sopenharmony_ci        }
3133920e296Sopenharmony_ci    }
3143920e296Sopenharmony_ci    return false;
3153920e296Sopenharmony_ci}
3163920e296Sopenharmony_ci
3173920e296Sopenharmony_cibool ConfigParser::IsHomeAction(const cJSON *actions)
3183920e296Sopenharmony_ci{
3193920e296Sopenharmony_ci    if (!actions || !cJSON_IsArray(actions)) {
3203920e296Sopenharmony_ci        return false;
3213920e296Sopenharmony_ci    }
3223920e296Sopenharmony_ci    for (cJSON *action = actions->child; action; action = action->next) {
3233920e296Sopenharmony_ci        if (!cJSON_IsObject(action)) {
3243920e296Sopenharmony_ci            return false;
3253920e296Sopenharmony_ci        }
3263920e296Sopenharmony_ci        if (strcmp(action->valuestring, "action.system.home") == 0) {
3273920e296Sopenharmony_ci            return true;
3283920e296Sopenharmony_ci        }
3293920e296Sopenharmony_ci    }
3303920e296Sopenharmony_ci    return false;
3313920e296Sopenharmony_ci}
3323920e296Sopenharmony_ci
3333920e296Sopenharmony_cibool ConfigParser::ParseRefImpl(cJSON *parent, const string &key, cJSON *node)
3343920e296Sopenharmony_ci{
3353920e296Sopenharmony_ci    if (cJSON_IsArray(node)) {
3363920e296Sopenharmony_ci        const auto &result = JSON_ARRAY_IDS.find(key);
3373920e296Sopenharmony_ci        if (result != JSON_ARRAY_IDS.end()) {
3383920e296Sopenharmony_ci            return ParseJsonArrayRef(parent, key, node);
3393920e296Sopenharmony_ci        }
3403920e296Sopenharmony_ci        cJSON *arrayItem = node->child;
3413920e296Sopenharmony_ci        while (arrayItem) {
3423920e296Sopenharmony_ci            if (!ParseRefImpl(node, "", arrayItem)) {
3433920e296Sopenharmony_ci                return false;
3443920e296Sopenharmony_ci            }
3453920e296Sopenharmony_ci            arrayItem = arrayItem->next;
3463920e296Sopenharmony_ci        }
3473920e296Sopenharmony_ci    } else if (cJSON_IsObject(node)) {
3483920e296Sopenharmony_ci        cJSON *child = node->child;
3493920e296Sopenharmony_ci        while (child) {
3503920e296Sopenharmony_ci            if (!ParseRefImpl(node, child->string, child)) {
3513920e296Sopenharmony_ci                return false;
3523920e296Sopenharmony_ci            }
3533920e296Sopenharmony_ci            child = child->next;
3543920e296Sopenharmony_ci        }
3553920e296Sopenharmony_ci    } else if (!key.empty() && cJSON_IsString(node)) {
3563920e296Sopenharmony_ci        return ParseJsonStringRef(parent, key, node);
3573920e296Sopenharmony_ci    }
3583920e296Sopenharmony_ci    return true;
3593920e296Sopenharmony_ci}
3603920e296Sopenharmony_ci
3613920e296Sopenharmony_cibool ConfigParser::ParseJsonArrayRef(cJSON *parent, const string &key, cJSON *node)
3623920e296Sopenharmony_ci{
3633920e296Sopenharmony_ci    if (!node || !cJSON_IsArray(node)) {
3643920e296Sopenharmony_ci        cerr << "Error: '"<< key << "'node not array." << NEW_LINE_PATH << filePath_ << endl;
3653920e296Sopenharmony_ci        return false;
3663920e296Sopenharmony_ci    }
3673920e296Sopenharmony_ci    cJSON *array = cJSON_CreateArray();
3683920e296Sopenharmony_ci    for (cJSON *item = node->child; item; item = item->next) {
3693920e296Sopenharmony_ci        if (!cJSON_IsString(item)) {
3703920e296Sopenharmony_ci            cerr << "Error: '" << key << "' invalid value." << NEW_LINE_PATH << filePath_ << endl;
3713920e296Sopenharmony_ci            cJSON_Delete(array);
3723920e296Sopenharmony_ci            return false;
3733920e296Sopenharmony_ci        }
3743920e296Sopenharmony_ci        string value = item->valuestring;
3753920e296Sopenharmony_ci        bool update = false;
3763920e296Sopenharmony_ci        if (!GetRefIdFromString(value, update, JSON_ARRAY_IDS.at(key))) {
3773920e296Sopenharmony_ci            cerr << "Error: '" << key << "' value " << value << " invalid." << NEW_LINE_PATH << filePath_ << endl;
3783920e296Sopenharmony_ci            cJSON_Delete(array);
3793920e296Sopenharmony_ci            return false;
3803920e296Sopenharmony_ci        }
3813920e296Sopenharmony_ci        if (update) {
3823920e296Sopenharmony_ci            cJSON_AddItemToArray(array, cJSON_CreateNumber(atoll(value.c_str())));
3833920e296Sopenharmony_ci        }
3843920e296Sopenharmony_ci    }
3853920e296Sopenharmony_ci    cJSON_AddItemToObject(parent, (key + "Id").c_str(), array);
3863920e296Sopenharmony_ci    cJSON_Delete(array);
3873920e296Sopenharmony_ci    return true;
3883920e296Sopenharmony_ci}
3893920e296Sopenharmony_ci
3903920e296Sopenharmony_cibool ConfigParser::ParseJsonStringRef(cJSON *parent, const string &key, cJSON *node)
3913920e296Sopenharmony_ci{
3923920e296Sopenharmony_ci    const auto &result = JSON_STRING_IDS.find(key);
3933920e296Sopenharmony_ci    if (result == JSON_STRING_IDS.end()) {
3943920e296Sopenharmony_ci        return true;
3953920e296Sopenharmony_ci    }
3963920e296Sopenharmony_ci    if (!node || !cJSON_IsString(node)) {
3973920e296Sopenharmony_ci        cerr << "Error: '" << key << "' invalid value." << endl;
3983920e296Sopenharmony_ci        return false;
3993920e296Sopenharmony_ci    }
4003920e296Sopenharmony_ci    string value = node->valuestring;
4013920e296Sopenharmony_ci    bool update = false;
4023920e296Sopenharmony_ci    if (!GetRefIdFromString(value, update, JSON_STRING_IDS.at(key))) {
4033920e296Sopenharmony_ci        cerr << "Error: '" << key << "' value " << value << " invalid value." << NEW_LINE_PATH << filePath_ << endl;
4043920e296Sopenharmony_ci        cerr << SOLUTIONS << endl;
4053920e296Sopenharmony_ci        cerr << SOLUTIONS_ARROW << "Please check the module.json5/config.json file in the src/main directory of the "
4063920e296Sopenharmony_ci             << GetModuleName() << "' module." << endl;
4073920e296Sopenharmony_ci        return false;
4083920e296Sopenharmony_ci    }
4093920e296Sopenharmony_ci    if (update) {
4103920e296Sopenharmony_ci        cJSON_AddItemToObject(parent, (key + "Id").c_str(), cJSON_CreateNumber(atoll(value.c_str())));
4113920e296Sopenharmony_ci        AddCheckNode(key, static_cast<uint32_t>(atoll(value.c_str())));
4123920e296Sopenharmony_ci    }
4133920e296Sopenharmony_ci    return true;
4143920e296Sopenharmony_ci}
4153920e296Sopenharmony_ci
4163920e296Sopenharmony_civoid ConfigParser::AddCheckNode(const string &key, uint32_t id)
4173920e296Sopenharmony_ci{
4183920e296Sopenharmony_ci    if (g_keyNodeIndexs.find(key) != g_keyNodeIndexs.end()) {
4193920e296Sopenharmony_ci        auto result = jsonCheckIds_.find(key);
4203920e296Sopenharmony_ci        if (result == jsonCheckIds_.end()) {
4213920e296Sopenharmony_ci            set<uint32_t> set;
4223920e296Sopenharmony_ci            set.emplace(id);
4233920e296Sopenharmony_ci            jsonCheckIds_.emplace(key, set);
4243920e296Sopenharmony_ci        } else {
4253920e296Sopenharmony_ci            result->second.emplace(id);
4263920e296Sopenharmony_ci        }
4273920e296Sopenharmony_ci        auto layerIconIds = ReferenceParser::GetLayerIconIds();
4283920e296Sopenharmony_ci        if (layerIconIds.find(id) != layerIconIds.end()) {
4293920e296Sopenharmony_ci            auto ids = layerIconIds[id];
4303920e296Sopenharmony_ci            jsonCheckIds_[key].insert(ids.begin(), ids.end());
4313920e296Sopenharmony_ci        }
4323920e296Sopenharmony_ci    }
4333920e296Sopenharmony_ci}
4343920e296Sopenharmony_ci
4353920e296Sopenharmony_cibool ConfigParser::GetRefIdFromString(string &value, bool &update, const string &match) const
4363920e296Sopenharmony_ci{
4373920e296Sopenharmony_ci    ReferenceParser refParser;
4383920e296Sopenharmony_ci    string error = "Error: '" + value + "' must start with '" + match.substr(match.find("\\") + 1) + "'";
4393920e296Sopenharmony_ci    if (refParser.ParseRefInString(value, update) != RESTOOL_SUCCESS) {
4403920e296Sopenharmony_ci        return false;
4413920e296Sopenharmony_ci    }
4423920e296Sopenharmony_ci    if (!update) {
4433920e296Sopenharmony_ci        return true;
4443920e296Sopenharmony_ci    }
4453920e296Sopenharmony_ci    smatch result;
4463920e296Sopenharmony_ci    if (regex_search(value, result, regex(match))) {
4473920e296Sopenharmony_ci        value = value.substr(result[0].str().length());
4483920e296Sopenharmony_ci        return true;
4493920e296Sopenharmony_ci    }
4503920e296Sopenharmony_ci    cerr << error << endl;
4513920e296Sopenharmony_ci    return false;
4523920e296Sopenharmony_ci}
4533920e296Sopenharmony_ci
4543920e296Sopenharmony_cibool ConfigParser::ParseModuleType(const string &type)
4553920e296Sopenharmony_ci{
4563920e296Sopenharmony_ci    const auto &result = MODULE_TYPES.find(type);
4573920e296Sopenharmony_ci    if (result == MODULE_TYPES.end()) {
4583920e296Sopenharmony_ci        cerr << "Error: moduleType='" << type << "' invalid value." << NEW_LINE_PATH << filePath_ << endl;
4593920e296Sopenharmony_ci        return false;
4603920e296Sopenharmony_ci    }
4613920e296Sopenharmony_ci    moduleType_ = result->second;
4623920e296Sopenharmony_ci    return true;
4633920e296Sopenharmony_ci}
4643920e296Sopenharmony_ci}
4653920e296Sopenharmony_ci}
4663920e296Sopenharmony_ci}
467