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