• 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 #include "metav1_compat.h"
16 
17 #include <meta/ext/serialization/common_value_serializers.h>
18 
19 META_BEGIN_NAMESPACE()
20 namespace Serialization {
21 
22 constexpr Version NEW_VERSION(2, 0);
23 
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()), {}));
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 
141         BASE_NS::shared_ptr<IObjectNode> fobj(
142             new ObjectNode("PropertyFunction", "", ClassId::PropertyFunction, {}, BASE_NS::move(fmap)));
143 
144         BASE_NS::shared_ptr<IMapNode> map(new MapNode);
145         map->AddNode("function", fobj);
146 
147         return BASE_NS::shared_ptr<ISerNode>(new ObjectNode("Bind", "", ClassId::Bind, {}, BASE_NS::move(map)));
148     }
149 
RewriteBind(ISerNode::Ptr n)150     ISerNode::Ptr RewriteBind(ISerNode::Ptr n)
151     {
152         if (auto obj = interface_cast<IObjectNode>(n)) {
153             if (auto map = interface_cast<IMapNode>(obj->GetMembers())) {
154                 if (auto node = map->FindNode("Property")) {
155                     return ConstructBind(node);
156                 }
157             }
158         }
159         return nullptr;
160     }
161 
RewriteProperty(BASE_NS::string name,const IObjectNode & n)162     ISerNode::Ptr RewriteProperty(BASE_NS::string name, const IObjectNode& n)
163     {
164         ISerNode::Ptr value;
165         ISerNode::Ptr bind;
166         bool hasDefaultValue = false;
167         auto mapNode = CreateShared<MapNode>();
168 
169         if (auto m = interface_cast<IMapNode>(n.GetMembers())) {
170             for (auto&& node : m->GetMembers()) {
171                 auto nn = node.node;
172                 if (node.name == "bind") {
173                     bind = RewriteBind(nn);
174                 } else {
175                     if (node.name == "flags") {
176                         node.name = "__flags";
177                         nn = RewritePropertyFlags(nn);
178                     } else if (node.name == "defaultValue") {
179                         hasDefaultValue = true;
180                         nn = RewriteValueToAny(n.GetObjectId(), nn);
181                     } else if (node.name == "value" || node.name == "valueObject") {
182                         node.name = "values";
183                         value = RewriteValueToAny(n.GetObjectId(), nn);
184                         nn = ISerNode::Ptr(new ArrayNode({ value }));
185                     } else {
186                         nn = VisitNode(nn);
187                     }
188                     if (nn) {
189                         mapNode->AddNode(node.name, nn);
190                     }
191                 }
192             }
193             if (!value) {
194                 mapNode->AddNode("values", ISerNode::Ptr(new ArrayNode(BASE_NS::vector<ISerNode::Ptr> {})));
195                 if (!hasDefaultValue) {
196                     CORE_LOG_E("Invalid json file, property doesn't have value or defaultValue");
197                 }
198             } else if (!hasDefaultValue) {
199                 mapNode->AddNode("defaultValue", value);
200             }
201             if (bind) {
202                 if (auto v = mapNode->FindNode("values")) {
203                     if (auto arr = interface_cast<IArrayNode>(v)) {
204                         arr->AddNode(bind);
205                     }
206                 }
207             }
208             mapNode->AddNode("modifiers", ISerNode::Ptr(new ArrayNode(BASE_NS::vector<ISerNode::Ptr> {})));
209         }
210         return ISerNode::Ptr(new ObjectNode("Property", name, ClassId::StackProperty, n.GetInstanceId(), mapNode));
211     }
RewriteObject(BASE_NS::string name,IObjectNode & n)212     ISerNode::Ptr RewriteObject(BASE_NS::string name, IObjectNode& n)
213     {
214         if (IsV1Property(n.GetObjectId())) {
215             return RewriteProperty(name, n);
216         }
217         return ISerNode::Ptr(new ObjectNode(
218             n.GetObjectClassName(), n.GetObjectName(), n.GetObjectId(), n.GetInstanceId(), VisitNode(n.GetMembers())));
219     }
RewritePropertyMap(const NamedNode & node,BASE_NS::vector<ISerNode::Ptr> & properties)220     void RewritePropertyMap(const NamedNode& node, BASE_NS::vector<ISerNode::Ptr>& properties)
221     {
222         auto n = VisitNode(node.node);
223         if (auto map = interface_cast<IMapNode>(n)) {
224             if (auto m = map->FindNode("__attachments")) {
225                 if (auto arr = interface_cast<IArrayNode>(m)) {
226                     for (auto&& an : arr->GetMembers()) {
227                         // the rewrite was already done by the above VisitNode call
228                         properties.push_back(an);
229                     }
230                 }
231             }
232         }
233     }
AddProperties(BASE_NS::vector<ISerNode::Ptr> properties,IMapNode & map)234     void AddProperties(BASE_NS::vector<ISerNode::Ptr> properties, IMapNode& map)
235     {
236         if (auto p = interface_cast<IArrayNode>(map.FindNode("__attachments"))) {
237             for (auto&& n : properties) {
238                 p->AddNode(n);
239             }
240         } else {
241             map.AddNode("__attachments", IArrayNode::Ptr(new ArrayNode(properties)));
242         }
243     }
Visit(const IMapNode & n)244     void Visit(const IMapNode& n) override
245     {
246         BASE_NS::vector<NamedNode> map;
247         BASE_NS::vector<ISerNode::Ptr> properties;
248         for (auto&& m : n.GetMembers()) {
249             ISerNode::Ptr p;
250             if (auto obj = interface_cast<IObjectNode>(m.node)) {
251                 p = RewriteObject(m.name, *obj);
252                 if (IsV1Property(obj->GetObjectId())) {
253                     properties.push_back(p);
254                     p = nullptr;
255                 }
256             } else if (m.name == "__properties") {
257                 RewritePropertyMap(m, properties);
258                 p = nullptr;
259             } else {
260                 p = VisitNode(m.node);
261             }
262             if (p) {
263                 map.push_back(NamedNode { m.name, p });
264             }
265         }
266         auto mapNode = IMapNode::Ptr(new MapNode(BASE_NS::move(map)));
267         if (!properties.empty()) {
268             AddProperties(properties, *mapNode);
269         }
270         node = mapNode;
271     }
Visit(const INilNode & n)272     void Visit(const INilNode& n) override
273     {
274         node.reset(new NilNode);
275     }
Visit(const IBoolNode & n)276     void Visit(const IBoolNode& n) override
277     {
278         node.reset(new BoolNode(n.GetValue()));
279     }
Visit(const IDoubleNode & n)280     void Visit(const IDoubleNode& n) override
281     {
282         node.reset(new DoubleNode(n.GetValue()));
283     }
Visit(const IIntNode & n)284     void Visit(const IIntNode& n) override
285     {
286         node.reset(new IntNode(n.GetValue()));
287     }
Visit(const IUIntNode & n)288     void Visit(const IUIntNode& n) override
289     {
290         node.reset(new UIntNode(n.GetValue()));
291     }
Visit(const IStringNode & n)292     void Visit(const IStringNode& n) override
293     {
294         node.reset(new StringNode(n.GetValue()));
295     }
Visit(const IRefUriNode & n)296     void Visit(const IRefUriNode& n) override
297     {
298         node.reset(new RefNode(n.GetValue()));
299     }
Visit(const ISerNode &)300     void Visit(const ISerNode&) override
301     {
302         CORE_LOG_E("Unknown node type");
303     }
304 
305     ISerNode::Ptr node;
306 };
307 
Process(ISerNode::Ptr tree)308 ISerNode::Ptr MetaMigrateV1::Process(ISerNode::Ptr tree)
309 {
310     NodeVisitor v;
311     tree->Apply(v);
312     return v.node;
313 }
314 
315 } // namespace Serialization
316 META_END_NAMESPACE()
317