• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "metav1_compat.h"
17 
18 #include <meta/ext/serialization/common_value_serializers.h>
19 
20 META_BEGIN_NAMESPACE()
21 namespace Serialization {
22 
23 constexpr Version NEW_VERSION(2, 0);
24 using BasicMetaTypes = TypeList<float, double, bool, uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t,
25     int64_t, BASE_NS::Uid, BASE_NS::string, BASE_NS::string_view, BASE_NS::Math::Vec2, BASE_NS::Math::UVec2,
26     BASE_NS::Math::IVec2, BASE_NS::Math::Vec3, BASE_NS::Math::UVec3, BASE_NS::Math::IVec3, BASE_NS::Math::Vec4,
27     BASE_NS::Math::UVec4, BASE_NS::Math::IVec4, BASE_NS::Math::Quat, BASE_NS::Math::Mat3X3, BASE_NS::Math::Mat4X4>;
28 
IsV1Property(ObjectId oid)29 static bool IsV1Property(ObjectId oid)
30 {
31     static const BASE_NS::Uid propertyUid("00000000-0000-0000-5072-6f7065727479");
32     return oid.ToUid().data[1] == propertyUid.data[1];
33 }
34 
35 template<typename... Types>
CheckBasicMetaTypes(ObjectId oid,ObjectId & out,TypeList<Types...>)36 static bool CheckBasicMetaTypes(ObjectId oid, ObjectId& out, TypeList<Types...>)
37 {
38     return (false || ... ||
39             (UidFromType<Types[]>().data[0] == oid.ToUid().data[0] ? (out = UidFromType<Types>(), true) : false));
40 }
41 
IsV1BasicArray(ObjectId oid,ObjectId & out)42 static bool IsV1BasicArray(ObjectId oid, ObjectId& out)
43 {
44     return CheckBasicMetaTypes(oid, out, BasicMetaTypes {});
45 }
46 
IsV1Any(ObjectId oid)47 static bool IsV1Any(ObjectId oid)
48 {
49     static const BASE_NS::Uid anyUid("00000000-0000-0000-5479-706564416e79");
50     return oid.ToUid().data[1] == anyUid.data[1];
51 }
52 
MakeAny(ObjectId oid)53 static ObjectId MakeAny(ObjectId oid)
54 {
55     BASE_NS::Uid uid("00000000-0000-0000-4275-696c74416e79");
56     uid.data[0] = oid.ToUid().data[0];
57     return uid;
58 }
59 
MakeArrayAny(ObjectId oid)60 static ObjectId MakeArrayAny(ObjectId oid)
61 {
62     BASE_NS::Uid uid("00000000-0000-0000-4172-726179416e79");
63     uid.data[0] = oid.ToUid().data[0];
64     return uid;
65 }
66 
67 class NodeVisitor : public IntroduceInterfaces<ISerNodeVisitor> {
68 public:
VisitNode(ISerNode::Ptr node)69     static ISerNode::Ptr VisitNode(ISerNode::Ptr node)
70     {
71         if (!node) {
72             return nullptr;
73         }
74         NodeVisitor v;
75         node->Apply(v);
76         return v.node;
77     }
78 
Visit(const IRootNode & n)79     void Visit(const IRootNode& n) override
80     {
81         node.reset(new RootNode(VisitNode(n.GetObject()), NEW_VERSION, n.GetSerializerVersion()));
82     }
Visit(const IObjectNode & n)83     void Visit(const IObjectNode& n) override
84     {
85         node.reset(new ObjectNode(
86             n.GetObjectClassName(), n.GetObjectName(), n.GetObjectId(), n.GetInstanceId(), VisitNode(n.GetMembers())));
87     }
Visit(const IArrayNode & n)88     void Visit(const IArrayNode& n) override
89     {
90         BASE_NS::vector<ISerNode::Ptr> arr;
91         for (auto&& m : n.GetMembers()) {
92             if (auto n = VisitNode(m)) {
93                 arr.push_back(n);
94             }
95         }
96         node.reset(new ArrayNode(BASE_NS::move(arr)));
97     }
RewriteValueToAny(ObjectId property,ISerNode::Ptr node)98     ISerNode::Ptr RewriteValueToAny(ObjectId property, ISerNode::Ptr node)
99     {
100         if (auto n = interface_cast<IObjectNode>(node)) {
101             if (IsV1Any(n->GetObjectId())) {
102                 return ISerNode::Ptr(new ObjectNode("Any", n->GetObjectName(), MakeAny(n->GetObjectId()),
103                     n->GetInstanceId(), VisitNode(n->GetMembers())));
104             }
105         }
106         BASE_NS::vector<NamedNode> m;
107         if (auto n = VisitNode(node)) {
108             m.push_back(NamedNode { "value", n });
109         }
110         ObjectId any = MakeAny(property);
111         ObjectId uid;
112         if (IsV1BasicArray(property, uid)) {
113             any = MakeArrayAny(uid);
114         }
115         return ISerNode::Ptr(new ObjectNode("Any", "", any, {}, CreateShared<MapNode>(m)));
116     }
117 
RewritePropertyFlags(ISerNode::Ptr n)118     ISerNode::Ptr RewritePropertyFlags(ISerNode::Ptr n)
119     {
120         uint64_t value {};
121         uint64_t converted { uint64_t(ObjectFlagBits::SERIALIZE) };
122         if (ExtractNumber(n, value)) {
123             if (value & 8) {
124                 converted |= 8;
125             }
126             if (value & 128) {
127                 converted |= 16;
128             }
129             if (converted != uint64_t(ObjectFlagBits::SERIALIZE)) {
130                 return ISerNode::Ptr(new UIntNode(converted));
131             }
132         }
133         return nullptr;
134     }
135 
ConstructBind(ISerNode::Ptr n)136     ISerNode::Ptr ConstructBind(ISerNode::Ptr n)
137     {
138         BASE_NS::shared_ptr<IMapNode> fmap(new MapNode);
139         fmap->AddNode("source", n);
140         BASE_NS::shared_ptr<IObjectNode> fobj(
141             new ObjectNode("PropertyFunction", "", ClassId::PropertyFunction, {}, BASE_NS::move(fmap)));
142         BASE_NS::shared_ptr<IMapNode> map(new MapNode);
143         map->AddNode("function", fobj);
144         return BASE_NS::shared_ptr<ISerNode>(new ObjectNode("Bind", "", ClassId::Bind, {}, BASE_NS::move(map)));
145     }
RewriteBind(ISerNode::Ptr n)146     ISerNode::Ptr RewriteBind(ISerNode::Ptr n)
147     {
148         if (auto obj = interface_cast<IObjectNode>(n)) {
149             if (auto map = interface_cast<IMapNode>(obj->GetMembers())) {
150                 if (auto node = map->FindNode("Property")) {
151                     return ConstructBind(node);
152                 }
153             }
154         }
155         return nullptr;
156     }
RewriteProperty(BASE_NS::string name,const IObjectNode & n)157     ISerNode::Ptr RewriteProperty(BASE_NS::string name, const IObjectNode& n)
158     {
159         ISerNode::Ptr value;
160         ISerNode::Ptr bind;
161         bool hasDefaultValue = false;
162         auto mapNode = CreateShared<MapNode>();
163         if (auto m = interface_cast<IMapNode>(n.GetMembers())) {
164             for (auto&& node : m->GetMembers()) {
165                 auto nn = node.node;
166                 if (node.name == "bind") {
167                     bind = RewriteBind(nn);
168                 } else {
169                     if (node.name == "flags") {
170                         node.name = "__flags";
171                         nn = RewritePropertyFlags(nn);
172                     } else if (node.name == "defaultValue") {
173                         hasDefaultValue = true;
174                         nn = RewriteValueToAny(n.GetObjectId(), nn);
175                     } else if (node.name == "value" || node.name == "valueObject") {
176                         node.name = "values";
177                         value = RewriteValueToAny(n.GetObjectId(), nn);
178                         nn = ISerNode::Ptr(new ArrayNode({ value }));
179                     } else {
180                         nn = VisitNode(nn);
181                     }
182                     if (nn) {
183                         mapNode->AddNode(node.name, nn);
184                     }
185                 }
186             }
187             if (!value) {
188                 mapNode->AddNode("values", ISerNode::Ptr(new ArrayNode(BASE_NS::vector<ISerNode::Ptr> {})));
189                 if (!hasDefaultValue) {
190                     CORE_LOG_E("Invalid json file, property doesn't have value or defaultValue");
191                 }
192             } else if (!hasDefaultValue) {
193                 mapNode->AddNode("defaultValue", value);
194             }
195             if (bind) {
196                 if (auto v = mapNode->FindNode("values")) {
197                     if (auto arr = interface_cast<IArrayNode>(v)) {
198                         arr->AddNode(bind);
199                     }
200                 }
201             }
202             mapNode->AddNode("modifiers", ISerNode::Ptr(new ArrayNode(BASE_NS::vector<ISerNode::Ptr> {})));
203         }
204         return ISerNode::Ptr(new ObjectNode("Property", name, ClassId::StackProperty, n.GetInstanceId(), mapNode));
205     }
RewriteObject(BASE_NS::string name,IObjectNode & n)206     ISerNode::Ptr RewriteObject(BASE_NS::string name, IObjectNode& n)
207     {
208         if (IsV1Property(n.GetObjectId())) {
209             return RewriteProperty(name, n);
210         }
211         return ISerNode::Ptr(new ObjectNode(
212             n.GetObjectClassName(), n.GetObjectName(), n.GetObjectId(), n.GetInstanceId(), VisitNode(n.GetMembers())));
213     }
RewritePropertyMap(const NamedNode & node,BASE_NS::vector<ISerNode::Ptr> & properties)214     void RewritePropertyMap(const NamedNode& node, BASE_NS::vector<ISerNode::Ptr>& properties)
215     {
216         auto n = VisitNode(node.node);
217         if (auto map = interface_cast<IMapNode>(n)) {
218             if (auto m = map->FindNode("__attachments")) {
219                 if (auto arr = interface_cast<IArrayNode>(m)) {
220                     for (auto&& an : arr->GetMembers()) {
221                         // the rewrite was already done by the above VisitNode call
222                         properties.push_back(an);
223                     }
224                 }
225             }
226         }
227     }
AddProperties(BASE_NS::vector<ISerNode::Ptr> properties,IMapNode & map)228     void AddProperties(BASE_NS::vector<ISerNode::Ptr> properties, IMapNode& map)
229     {
230         if (auto p = interface_cast<IArrayNode>(map.FindNode("__attachments"))) {
231             for (auto&& n : properties) {
232                 p->AddNode(n);
233             }
234         } else {
235             map.AddNode("__attachments", IArrayNode::Ptr(new ArrayNode(properties)));
236         }
237     }
Visit(const IMapNode & n)238     void Visit(const IMapNode& n) override
239     {
240         BASE_NS::vector<NamedNode> map;
241         BASE_NS::vector<ISerNode::Ptr> properties;
242         for (auto&& m : n.GetMembers()) {
243             ISerNode::Ptr p;
244             if (auto obj = interface_cast<IObjectNode>(m.node)) {
245                 p = RewriteObject(m.name, *obj);
246                 if (IsV1Property(obj->GetObjectId())) {
247                     properties.push_back(p);
248                     p = nullptr;
249                 }
250             } else if (m.name == "__properties") {
251                 RewritePropertyMap(m, properties);
252                 p = nullptr;
253             } else {
254                 p = VisitNode(m.node);
255             }
256             if (p) {
257                 map.push_back(NamedNode { m.name, p });
258             }
259         }
260         auto mapNode = IMapNode::Ptr(new MapNode(BASE_NS::move(map)));
261         if (!properties.empty()) {
262             AddProperties(properties, *mapNode);
263         }
264         node = mapNode;
265     }
Visit(const INilNode & n)266     void Visit(const INilNode& n) override
267     {
268         node.reset(new NilNode);
269     }
Visit(const IBoolNode & n)270     void Visit(const IBoolNode& n) override
271     {
272         node.reset(new BoolNode(n.GetValue()));
273     }
Visit(const IDoubleNode & n)274     void Visit(const IDoubleNode& n) override
275     {
276         node.reset(new DoubleNode(n.GetValue()));
277     }
Visit(const IIntNode & n)278     void Visit(const IIntNode& n) override
279     {
280         node.reset(new IntNode(n.GetValue()));
281     }
Visit(const IUIntNode & n)282     void Visit(const IUIntNode& n) override
283     {
284         node.reset(new UIntNode(n.GetValue()));
285     }
Visit(const IStringNode & n)286     void Visit(const IStringNode& n) override
287     {
288         node.reset(new StringNode(n.GetValue()));
289     }
Visit(const IRefUriNode & n)290     void Visit(const IRefUriNode& n) override
291     {
292         node.reset(new RefNode(n.GetValue()));
293     }
Visit(const ISerNode &)294     void Visit(const ISerNode&) override
295     {
296         CORE_LOG_E("Unknown node type");
297     }
298 
299     ISerNode::Ptr node;
300 };
301 
Process(ISerNode::Ptr tree)302 ISerNode::Ptr MetaMigrateV1::Process(ISerNode::Ptr tree)
303 {
304     NodeVisitor v;
305     tree->Apply(v);
306     return v.node;
307 }
308 
309 } // namespace Serialization
310 META_END_NAMESPACE()
311