18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci#include "metav1_compat.h"
168bf80f4bSopenharmony_ci
178bf80f4bSopenharmony_ci#include <meta/ext/serialization/common_value_serializers.h>
188bf80f4bSopenharmony_ci
198bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
208bf80f4bSopenharmony_cinamespace Serialization {
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ciusing BasicMetaTypes = TypeList<float, double, bool, uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t,
238bf80f4bSopenharmony_ci    int64_t, BASE_NS::Uid, BASE_NS::string, BASE_NS::string_view, BASE_NS::Math::Vec2, BASE_NS::Math::UVec2,
248bf80f4bSopenharmony_ci    BASE_NS::Math::IVec2, BASE_NS::Math::Vec3, BASE_NS::Math::UVec3, BASE_NS::Math::IVec3, BASE_NS::Math::Vec4,
258bf80f4bSopenharmony_ci    BASE_NS::Math::UVec4, BASE_NS::Math::IVec4, BASE_NS::Math::Quat, BASE_NS::Math::Mat3X3, BASE_NS::Math::Mat4X4>;
268bf80f4bSopenharmony_ci
278bf80f4bSopenharmony_cistatic bool IsV1Property(ObjectId oid)
288bf80f4bSopenharmony_ci{
298bf80f4bSopenharmony_ci    static const BASE_NS::Uid propertyUid("00000000-0000-0000-5072-6f7065727479");
308bf80f4bSopenharmony_ci    return oid.ToUid().data[1] == propertyUid.data[1];
318bf80f4bSopenharmony_ci}
328bf80f4bSopenharmony_ci
338bf80f4bSopenharmony_citemplate<typename... Types>
348bf80f4bSopenharmony_cistatic bool CheckBasicMetaTypes(ObjectId oid, ObjectId& out, TypeList<Types...>)
358bf80f4bSopenharmony_ci{
368bf80f4bSopenharmony_ci    return (false || ... ||
378bf80f4bSopenharmony_ci            (UidFromType<Types[]>().data[0] == oid.ToUid().data[0] ? (out = UidFromType<Types>(), true) : false));
388bf80f4bSopenharmony_ci}
398bf80f4bSopenharmony_ci
408bf80f4bSopenharmony_cistatic bool IsV1BasicArray(ObjectId oid, ObjectId& out)
418bf80f4bSopenharmony_ci{
428bf80f4bSopenharmony_ci    return CheckBasicMetaTypes(oid, out, BasicMetaTypes {});
438bf80f4bSopenharmony_ci}
448bf80f4bSopenharmony_ci
458bf80f4bSopenharmony_cistatic bool IsV1Any(ObjectId oid)
468bf80f4bSopenharmony_ci{
478bf80f4bSopenharmony_ci    static const BASE_NS::Uid anyUid("00000000-0000-0000-5479-706564416e79");
488bf80f4bSopenharmony_ci    return oid.ToUid().data[1] == anyUid.data[1];
498bf80f4bSopenharmony_ci}
508bf80f4bSopenharmony_ci
518bf80f4bSopenharmony_cistatic ObjectId MakeAny(ObjectId oid)
528bf80f4bSopenharmony_ci{
538bf80f4bSopenharmony_ci    BASE_NS::Uid uid("00000000-0000-0000-4275-696c74416e79");
548bf80f4bSopenharmony_ci    uid.data[0] = oid.ToUid().data[0];
558bf80f4bSopenharmony_ci    return uid;
568bf80f4bSopenharmony_ci}
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_cistatic ObjectId MakeArrayAny(ObjectId oid)
598bf80f4bSopenharmony_ci{
608bf80f4bSopenharmony_ci    BASE_NS::Uid uid("00000000-0000-0000-4172-726179416e79");
618bf80f4bSopenharmony_ci    uid.data[0] = oid.ToUid().data[0];
628bf80f4bSopenharmony_ci    return uid;
638bf80f4bSopenharmony_ci}
648bf80f4bSopenharmony_ci
658bf80f4bSopenharmony_ciclass NodeVisitor : public IntroduceInterfaces<ISerNodeVisitor> {
668bf80f4bSopenharmony_cipublic:
678bf80f4bSopenharmony_ci    static ISerNode::Ptr VisitNode(ISerNode::Ptr node)
688bf80f4bSopenharmony_ci    {
698bf80f4bSopenharmony_ci        if (!node) {
708bf80f4bSopenharmony_ci            return nullptr;
718bf80f4bSopenharmony_ci        }
728bf80f4bSopenharmony_ci        NodeVisitor v;
738bf80f4bSopenharmony_ci        node->Apply(v);
748bf80f4bSopenharmony_ci        return v.node;
758bf80f4bSopenharmony_ci    }
768bf80f4bSopenharmony_ci
778bf80f4bSopenharmony_ci    void Visit(const IRootNode& n) override
788bf80f4bSopenharmony_ci    {
798bf80f4bSopenharmony_ci        node.reset(new RootNode(n.GetSerializerVersion(), VisitNode(n.GetObject())));
808bf80f4bSopenharmony_ci    }
818bf80f4bSopenharmony_ci    void Visit(const IObjectNode& n) override
828bf80f4bSopenharmony_ci    {
838bf80f4bSopenharmony_ci        node.reset(new ObjectNode(
848bf80f4bSopenharmony_ci            n.GetObjectClassName(), n.GetObjectName(), n.GetObjectId(), n.GetInstanceId(), VisitNode(n.GetMembers())));
858bf80f4bSopenharmony_ci    }
868bf80f4bSopenharmony_ci    void Visit(const IArrayNode& n) override
878bf80f4bSopenharmony_ci    {
888bf80f4bSopenharmony_ci        BASE_NS::vector<ISerNode::Ptr> arr;
898bf80f4bSopenharmony_ci        for (auto&& m : n.GetMembers()) {
908bf80f4bSopenharmony_ci            if (auto n = VisitNode(m)) {
918bf80f4bSopenharmony_ci                arr.push_back(n);
928bf80f4bSopenharmony_ci            }
938bf80f4bSopenharmony_ci        }
948bf80f4bSopenharmony_ci        node.reset(new ArrayNode(BASE_NS::move(arr)));
958bf80f4bSopenharmony_ci    }
968bf80f4bSopenharmony_ci    ISerNode::Ptr RewriteValueToAny(ObjectId property, ISerNode::Ptr node)
978bf80f4bSopenharmony_ci    {
988bf80f4bSopenharmony_ci        if (auto n = interface_cast<IObjectNode>(node)) {
998bf80f4bSopenharmony_ci            if (IsV1Any(n->GetObjectId())) {
1008bf80f4bSopenharmony_ci                return ISerNode::Ptr(new ObjectNode("Any", n->GetObjectName(), MakeAny(n->GetObjectId()),
1018bf80f4bSopenharmony_ci                    n->GetInstanceId(), VisitNode(n->GetMembers())));
1028bf80f4bSopenharmony_ci            }
1038bf80f4bSopenharmony_ci        }
1048bf80f4bSopenharmony_ci        BASE_NS::vector<NamedNode> m;
1058bf80f4bSopenharmony_ci        if (auto n = VisitNode(node)) {
1068bf80f4bSopenharmony_ci            m.push_back(NamedNode { "value", n });
1078bf80f4bSopenharmony_ci        }
1088bf80f4bSopenharmony_ci        ObjectId any = MakeAny(property);
1098bf80f4bSopenharmony_ci        ObjectId uid;
1108bf80f4bSopenharmony_ci        if (IsV1BasicArray(property, uid)) {
1118bf80f4bSopenharmony_ci            any = MakeArrayAny(uid);
1128bf80f4bSopenharmony_ci        }
1138bf80f4bSopenharmony_ci        return ISerNode::Ptr(new ObjectNode("Any", "", any, {}, CreateShared<MapNode>(m)));
1148bf80f4bSopenharmony_ci    }
1158bf80f4bSopenharmony_ci
1168bf80f4bSopenharmony_ci    ISerNode::Ptr RewritePropertyFlags(ISerNode::Ptr n)
1178bf80f4bSopenharmony_ci    {
1188bf80f4bSopenharmony_ci        uint64_t value {};
1198bf80f4bSopenharmony_ci        uint64_t converted { uint64_t(ObjectFlagBits::SERIALIZE) };
1208bf80f4bSopenharmony_ci        if (ExtractNumber(n, value)) {
1218bf80f4bSopenharmony_ci            if (value & 8) {
1228bf80f4bSopenharmony_ci                converted |= 8;
1238bf80f4bSopenharmony_ci            }
1248bf80f4bSopenharmony_ci            if (value & 128) {
1258bf80f4bSopenharmony_ci                converted |= 16;
1268bf80f4bSopenharmony_ci            }
1278bf80f4bSopenharmony_ci            if (converted != uint64_t(ObjectFlagBits::SERIALIZE)) {
1288bf80f4bSopenharmony_ci                return ISerNode::Ptr(new UIntNode(converted));
1298bf80f4bSopenharmony_ci            }
1308bf80f4bSopenharmony_ci        }
1318bf80f4bSopenharmony_ci        return nullptr;
1328bf80f4bSopenharmony_ci    }
1338bf80f4bSopenharmony_ci
1348bf80f4bSopenharmony_ci    ISerNode::Ptr RewriteProperty(BASE_NS::string name, const IObjectNode& n)
1358bf80f4bSopenharmony_ci    {
1368bf80f4bSopenharmony_ci        BASE_NS::vector<NamedNode> map;
1378bf80f4bSopenharmony_ci        ISerNode::Ptr value;
1388bf80f4bSopenharmony_ci        bool hasDefaultValue = false;
1398bf80f4bSopenharmony_ci        if (auto m = interface_cast<IMapNode>(n.GetMembers())) {
1408bf80f4bSopenharmony_ci            for (auto&& node : m->GetMembers()) {
1418bf80f4bSopenharmony_ci                auto nn = node.node;
1428bf80f4bSopenharmony_ci                if (node.name == "flags") {
1438bf80f4bSopenharmony_ci                    node.name = "__flags";
1448bf80f4bSopenharmony_ci                    nn = RewritePropertyFlags(nn);
1458bf80f4bSopenharmony_ci                } else if (node.name == "defaultValue") {
1468bf80f4bSopenharmony_ci                    hasDefaultValue = true;
1478bf80f4bSopenharmony_ci                    nn = RewriteValueToAny(n.GetObjectId(), nn);
1488bf80f4bSopenharmony_ci                } else if (node.name == "value" || node.name == "valueObject") {
1498bf80f4bSopenharmony_ci                    node.name = "values";
1508bf80f4bSopenharmony_ci                    value = RewriteValueToAny(n.GetObjectId(), nn);
1518bf80f4bSopenharmony_ci                    nn = ISerNode::Ptr(new ArrayNode({ value }));
1528bf80f4bSopenharmony_ci                } else {
1538bf80f4bSopenharmony_ci                    nn = VisitNode(nn);
1548bf80f4bSopenharmony_ci                }
1558bf80f4bSopenharmony_ci                if (nn) {
1568bf80f4bSopenharmony_ci                    map.push_back(NamedNode { node.name, nn });
1578bf80f4bSopenharmony_ci                }
1588bf80f4bSopenharmony_ci            }
1598bf80f4bSopenharmony_ci            if (!value) {
1608bf80f4bSopenharmony_ci                map.push_back(NamedNode { "values", ISerNode::Ptr(new ArrayNode(BASE_NS::vector<ISerNode::Ptr> {})) });
1618bf80f4bSopenharmony_ci                if (!hasDefaultValue) {
1628bf80f4bSopenharmony_ci                    CORE_LOG_E("Invalid json file, property doesn't have value or defaultValue");
1638bf80f4bSopenharmony_ci                }
1648bf80f4bSopenharmony_ci            } else if (!hasDefaultValue) {
1658bf80f4bSopenharmony_ci                map.push_back(NamedNode { "defaultValue", value });
1668bf80f4bSopenharmony_ci            }
1678bf80f4bSopenharmony_ci            map.push_back(NamedNode { "modifiers", ISerNode::Ptr(new ArrayNode(BASE_NS::vector<ISerNode::Ptr> {})) });
1688bf80f4bSopenharmony_ci        }
1698bf80f4bSopenharmony_ci        auto mapNode = CreateShared<MapNode>(BASE_NS::move(map));
1708bf80f4bSopenharmony_ci        return ISerNode::Ptr(new ObjectNode("Property", name, ClassId::StackProperty, n.GetInstanceId(), mapNode));
1718bf80f4bSopenharmony_ci    }
1728bf80f4bSopenharmony_ci    ISerNode::Ptr RewriteObject(BASE_NS::string name, IObjectNode& n)
1738bf80f4bSopenharmony_ci    {
1748bf80f4bSopenharmony_ci        if (IsV1Property(n.GetObjectId())) {
1758bf80f4bSopenharmony_ci            return RewriteProperty(name, n);
1768bf80f4bSopenharmony_ci        }
1778bf80f4bSopenharmony_ci        return ISerNode::Ptr(new ObjectNode(
1788bf80f4bSopenharmony_ci            n.GetObjectClassName(), n.GetObjectName(), n.GetObjectId(), n.GetInstanceId(), VisitNode(n.GetMembers())));
1798bf80f4bSopenharmony_ci    }
1808bf80f4bSopenharmony_ci    ISerNode::Ptr RewritePropertyMap(const NamedNode& node)
1818bf80f4bSopenharmony_ci    {
1828bf80f4bSopenharmony_ci        BASE_NS::vector<ISerNode::Ptr> arr;
1838bf80f4bSopenharmony_ci        auto n = VisitNode(node.node);
1848bf80f4bSopenharmony_ci        if (auto map = interface_cast<IMapNode>(n)) {
1858bf80f4bSopenharmony_ci            for (auto&& m : map->GetMembers()) {
1868bf80f4bSopenharmony_ci                // the rewrite was already done by the above VisitNode call
1878bf80f4bSopenharmony_ci                arr.push_back(m.node);
1888bf80f4bSopenharmony_ci            }
1898bf80f4bSopenharmony_ci        }
1908bf80f4bSopenharmony_ci        return ISerNode::Ptr(new ArrayNode(arr));
1918bf80f4bSopenharmony_ci    }
1928bf80f4bSopenharmony_ci    void AddProperties(BASE_NS::vector<ISerNode::Ptr> properties, IMapNode& map)
1938bf80f4bSopenharmony_ci    {
1948bf80f4bSopenharmony_ci        if (auto p = interface_cast<IArrayNode>(map.FindNode("__properties"))) {
1958bf80f4bSopenharmony_ci            for (auto&& n : properties) {
1968bf80f4bSopenharmony_ci                p->AddNode(n);
1978bf80f4bSopenharmony_ci            }
1988bf80f4bSopenharmony_ci        } else {
1998bf80f4bSopenharmony_ci            map.AddNode("__properties", IArrayNode::Ptr(new ArrayNode(properties)));
2008bf80f4bSopenharmony_ci        }
2018bf80f4bSopenharmony_ci    }
2028bf80f4bSopenharmony_ci    void Visit(const IMapNode& n) override
2038bf80f4bSopenharmony_ci    {
2048bf80f4bSopenharmony_ci        BASE_NS::vector<NamedNode> map;
2058bf80f4bSopenharmony_ci        BASE_NS::vector<ISerNode::Ptr> properties;
2068bf80f4bSopenharmony_ci        for (auto&& m : n.GetMembers()) {
2078bf80f4bSopenharmony_ci            ISerNode::Ptr p;
2088bf80f4bSopenharmony_ci            if (auto obj = interface_cast<IObjectNode>(m.node)) {
2098bf80f4bSopenharmony_ci                p = RewriteObject(m.name, *obj);
2108bf80f4bSopenharmony_ci                if (IsV1Property(obj->GetObjectId())) {
2118bf80f4bSopenharmony_ci                    properties.push_back(p);
2128bf80f4bSopenharmony_ci                    p = nullptr;
2138bf80f4bSopenharmony_ci                }
2148bf80f4bSopenharmony_ci            } else if (m.name == "__properties") {
2158bf80f4bSopenharmony_ci                p = RewritePropertyMap(m);
2168bf80f4bSopenharmony_ci            } else {
2178bf80f4bSopenharmony_ci                p = VisitNode(m.node);
2188bf80f4bSopenharmony_ci            }
2198bf80f4bSopenharmony_ci            if (p) {
2208bf80f4bSopenharmony_ci                map.push_back(NamedNode { m.name, p });
2218bf80f4bSopenharmony_ci            }
2228bf80f4bSopenharmony_ci        }
2238bf80f4bSopenharmony_ci        auto mapNode = IMapNode::Ptr(new MapNode(BASE_NS::move(map)));
2248bf80f4bSopenharmony_ci        if (!properties.empty()) {
2258bf80f4bSopenharmony_ci            AddProperties(properties, *mapNode);
2268bf80f4bSopenharmony_ci        }
2278bf80f4bSopenharmony_ci        node = mapNode;
2288bf80f4bSopenharmony_ci    }
2298bf80f4bSopenharmony_ci    void Visit(const INilNode& n) override
2308bf80f4bSopenharmony_ci    {
2318bf80f4bSopenharmony_ci        node.reset(new NilNode);
2328bf80f4bSopenharmony_ci    }
2338bf80f4bSopenharmony_ci    void Visit(const IBoolNode& n) override
2348bf80f4bSopenharmony_ci    {
2358bf80f4bSopenharmony_ci        node.reset(new BoolNode(n.GetValue()));
2368bf80f4bSopenharmony_ci    }
2378bf80f4bSopenharmony_ci    void Visit(const IDoubleNode& n) override
2388bf80f4bSopenharmony_ci    {
2398bf80f4bSopenharmony_ci        node.reset(new DoubleNode(n.GetValue()));
2408bf80f4bSopenharmony_ci    }
2418bf80f4bSopenharmony_ci    void Visit(const IIntNode& n) override
2428bf80f4bSopenharmony_ci    {
2438bf80f4bSopenharmony_ci        node.reset(new IntNode(n.GetValue()));
2448bf80f4bSopenharmony_ci    }
2458bf80f4bSopenharmony_ci    void Visit(const IUIntNode& n) override
2468bf80f4bSopenharmony_ci    {
2478bf80f4bSopenharmony_ci        node.reset(new UIntNode(n.GetValue()));
2488bf80f4bSopenharmony_ci    }
2498bf80f4bSopenharmony_ci    void Visit(const IStringNode& n) override
2508bf80f4bSopenharmony_ci    {
2518bf80f4bSopenharmony_ci        node.reset(new StringNode(n.GetValue()));
2528bf80f4bSopenharmony_ci    }
2538bf80f4bSopenharmony_ci    void Visit(const IRefUriNode& n) override
2548bf80f4bSopenharmony_ci    {
2558bf80f4bSopenharmony_ci        node.reset(new RefNode(n.GetValue()));
2568bf80f4bSopenharmony_ci    }
2578bf80f4bSopenharmony_ci    void Visit(const ISerNode&) override
2588bf80f4bSopenharmony_ci    {
2598bf80f4bSopenharmony_ci        CORE_LOG_E("Unknown node type");
2608bf80f4bSopenharmony_ci    }
2618bf80f4bSopenharmony_ci
2628bf80f4bSopenharmony_ci    ISerNode::Ptr node;
2638bf80f4bSopenharmony_ci};
2648bf80f4bSopenharmony_ci
2658bf80f4bSopenharmony_ciISerNode::Ptr RewriteMetaV1NodeTree(ISerNode::Ptr tree)
2668bf80f4bSopenharmony_ci{
2678bf80f4bSopenharmony_ci    NodeVisitor v;
2688bf80f4bSopenharmony_ci    tree->Apply(v);
2698bf80f4bSopenharmony_ci    return v.node;
2708bf80f4bSopenharmony_ci}
2718bf80f4bSopenharmony_ci
2728bf80f4bSopenharmony_ci} // namespace Serialization
2738bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
274