1 /* 2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3 * 4 * HDF is dual licensed: you can use it either under the terms of 5 * the GPL, or the BSD license, at your option. 6 * See the LICENSE file in the root of this repository for complete details. 7 */ 8 9 #ifndef HC_GEN_AST_H 10 #define HC_GEN_AST_H 11 12 #include <list> 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 #include "token.h" 18 #include "types.h" 19 20 namespace OHOS { 21 namespace Hardware { 22 enum ObjectType { 23 PARSEROP_UINT8 = 0x01, 24 PARSEROP_UINT16, 25 PARSEROP_UINT32, 26 PARSEROP_UINT64, 27 PARSEROP_STRING, 28 PARSEROP_CONFNODE, 29 PARSEROP_CONFTERM, 30 PARSEROP_ARRAY, 31 PARSEROP_NODEREF, 32 PARSEROP_DELETE, 33 }; 34 35 enum NodeRefType { 36 NODE_NOREF = 0, 37 NODE_COPY, 38 NODE_REF, 39 NODE_DELETE, 40 NODE_TEMPLATE, 41 NODE_INHERIT, 42 }; 43 44 class AstObject { 45 public: 46 friend class Ast; 47 48 AstObject(const std::string &name, uint32_t type, uint64_t integerValue, const std::string &strValue, 49 uint32_t lineno, const std::shared_ptr<std::string> &src); 50 51 AstObject(const std::string &name, uint32_t type, uint64_t integerValue); 52 53 AstObject(const std::string &name, uint32_t type, const std::string &strValue); 54 55 AstObject(const std::string &name, uint32_t type, uint64_t integerValue, const Token &bindToken); 56 57 AstObject(const std::string &name, uint32_t type, const std::string &strValue, const Token &bindToken); 58 59 AstObject(const AstObject &obj); 60 61 virtual ~AstObject(); 62 63 AstObject &operator=(const AstObject &obj); 64 65 virtual bool AddChild(const std::shared_ptr<AstObject> &childObj); 66 67 virtual bool AddPeer(std::shared_ptr<AstObject> peerObject); 68 69 friend std::ostream &operator<<(std::ostream &stream, const AstObject &t); 70 71 virtual bool Merge(std::shared_ptr<AstObject> &srcObj); 72 73 virtual bool Copy(std::shared_ptr<AstObject> src, bool overwrite); 74 75 virtual bool Move(std::shared_ptr<AstObject> src); 76 77 void Remove(); 78 79 void Separate(); 80 81 std::shared_ptr<AstObject> Lookup(const std::string &name, uint32_t type = 0) const; 82 83 bool IsElders(const std::shared_ptr<AstObject> &child) const; 84 85 bool IsNumber() const; 86 87 bool IsNode() const; 88 89 bool IsTerm() const; 90 91 bool IsArray() const; 92 93 virtual std::string SourceInfo(); 94 95 void SetParent(AstObject *parent); 96 97 void SetSize(uint32_t size); 98 99 void SetSubSize(uint32_t size); 100 101 void SetHash(uint32_t hash); 102 103 uint32_t GetSize() const; 104 105 uint32_t GetSubSize() const; 106 107 uint32_t GetHash() const; 108 109 std::shared_ptr<AstObject> Child(); 110 111 std::shared_ptr<AstObject> Next(); 112 113 virtual const std::string &Name(); 114 115 const std::string &StringValue() const; 116 117 uint64_t IntegerValue() const; 118 119 virtual uint32_t Type(); 120 121 uint8_t OpCode() const; 122 123 void SetOpCode(uint8_t opcode); 124 125 virtual bool HasDuplicateChild(); 126 127 std::shared_ptr<AstObject> Parent() const; 128 129 protected: 130 uint32_t type_; 131 std::string name_; 132 AstObject *parent_; 133 std::shared_ptr<AstObject> next_; 134 std::shared_ptr<AstObject> child_; 135 uint32_t lineno_; 136 std::shared_ptr<std::string> src_; 137 uint8_t opCode_; 138 uint32_t size_; 139 uint32_t subSize_; 140 uint32_t hash_; 141 uint64_t integerValue_; 142 std::string stringValue_; 143 144 private: 145 static uint32_t FitIntegerValueType(uint64_t value); 146 }; 147 148 class ConfigNode : public AstObject { 149 public: 150 ConfigNode(const ConfigNode &node); 151 152 ConfigNode(const std::string &name, uint32_t nodeType, const std::string &refName); 153 154 ConfigNode(Token &name, uint32_t nodeType, const std::string &refName); 155 156 ~ConfigNode() override = default; 157 158 ConfigNode &operator=(const ConfigNode &node); 159 160 friend std::ostream &operator<<(std::ostream &stream, const ConfigNode &t); 161 162 bool Merge(std::shared_ptr<AstObject> &srcObj) override; 163 164 static ConfigNode *CastFrom(const std::shared_ptr<AstObject> &astObject); 165 166 uint32_t GetNodeType() const; 167 168 const std::string &GetRefPath() const; 169 170 void SetNodeType(uint32_t nodeType); 171 172 void SetRefPath(const std::string &ref); 173 174 static const std::string &NodeTypeToStr(uint32_t type); 175 176 bool HasDuplicateChild() override; 177 178 bool InheritExpand(const std::shared_ptr<AstObject> &refObj); 179 180 bool RefExpand(const std::shared_ptr<AstObject> &refObj); 181 182 bool Copy(std::shared_ptr<AstObject> src, bool overwrite) override; 183 184 bool Move(std::shared_ptr<AstObject> src) override; 185 186 bool Compare(ConfigNode &other) const; 187 188 bool IsBaseNode(); 189 190 uint32_t InheritIndex() const; 191 192 uint32_t InheritCount() const; 193 194 uint32_t TemplateSignNum() const; 195 196 void SetTemplateSignNum(uint32_t sigNum); 197 198 const std::list<AstObject *> &SubClasses() const; 199 200 private: 201 bool NodeRefExpand(const std::shared_ptr<AstObject> &ref); 202 203 bool NodeCopyExpand(const std::shared_ptr<AstObject> &ref); 204 205 std::string refNodePath_; 206 uint32_t nodeType_; 207 uint32_t inheritIndex_; 208 uint32_t inheritCount_; 209 uint32_t templateSignNum_; 210 std::list<AstObject *> subClasses_; 211 }; 212 213 class ConfigTerm : public AstObject { 214 public: 215 ConfigTerm(const ConfigTerm &term); 216 217 ConfigTerm(const std::string &name, const std::shared_ptr<AstObject> &value); 218 219 ConfigTerm(Token &name, const std::shared_ptr<AstObject> &value); 220 221 ~ConfigTerm() override = default; 222 223 ConfigTerm &operator=(const ConfigTerm &term); 224 225 static ConfigTerm *CastFrom(const std::shared_ptr<AstObject> &astObject); 226 227 bool Merge(std::shared_ptr<AstObject> &srcObj) override; 228 229 friend std::ostream &operator<<(std::ostream &stream, const ConfigTerm &t); 230 231 bool RefExpand(const std::shared_ptr<AstObject> refObj); 232 233 bool Copy(std::shared_ptr<AstObject> src, bool overwrite) override; 234 235 bool Move(std::shared_ptr<AstObject> src) override; 236 237 std::weak_ptr<AstObject> RefNode(); 238 239 uint32_t SigNum() const; 240 241 void SetSigNum(uint32_t sigNum); 242 243 private: 244 std::weak_ptr<AstObject> refNode_; 245 uint32_t signNum_; 246 }; 247 248 class ConfigArray : public AstObject { 249 public: 250 ConfigArray(); 251 252 ConfigArray(const ConfigArray &array); 253 254 explicit ConfigArray(const Token &bindToken); 255 256 ~ConfigArray() override = default; 257 258 ConfigArray &operator=(const ConfigArray &array); 259 260 static ConfigArray *CastFrom(const std::shared_ptr<AstObject> &astObject); 261 262 bool AddChild(const std::shared_ptr<AstObject> &childObj) override; 263 264 bool Merge(std::shared_ptr<AstObject> &srcObj) override; 265 266 bool Copy(std::shared_ptr<AstObject> src, bool overwrite) override; 267 268 uint16_t ArraySize() const; 269 270 uint16_t ArrayType() const; 271 272 private: 273 uint32_t arrayType_; 274 uint32_t arraySize_; 275 }; 276 277 class AstObjectFactory { 278 public: 279 static std::shared_ptr<AstObject> Build(std::shared_ptr<AstObject> object); 280 }; 281 282 class Ast { 283 public: Ast(std::shared_ptr<AstObject> astRoot)284 explicit Ast(std::shared_ptr<AstObject> astRoot) : astRoot_(std::move(astRoot)), redefineChecked_(false) {} 285 286 ~Ast() = default; 287 288 std::shared_ptr<AstObject> GetAstRoot(); 289 290 bool Merge(const std::list<std::shared_ptr<Ast>> &astList); 291 292 bool Expand(); 293 294 std::shared_ptr<AstObject> Lookup(const std::shared_ptr<AstObject> &startObj, const std::string &path); 295 296 template <typename T> WalkForward(const std::shared_ptr<AstObject> & startObject,T callback)297 static bool WalkForward(const std::shared_ptr<AstObject> &startObject, T callback) 298 { 299 std::shared_ptr<AstObject> forwardWalkObj = startObject; 300 int32_t walkDepth = 0; 301 bool preVisited = false; 302 303 while (forwardWalkObj != nullptr) { 304 if (!preVisited) { 305 int32_t ret = static_cast<int32_t>(callback(forwardWalkObj, walkDepth)); 306 if (ret && ret != EASTWALKBREAK) { 307 return false; 308 } else if (ret != EASTWALKBREAK && forwardWalkObj->child_ != nullptr) { 309 /* when callback return EASTWALKBREAK, not walk current's child */ 310 walkDepth++; 311 forwardWalkObj = forwardWalkObj->child_; 312 continue; 313 } 314 } 315 if (forwardWalkObj == startObject) { 316 break; 317 } 318 319 if (forwardWalkObj->next_ != nullptr) { 320 forwardWalkObj = forwardWalkObj->next_; 321 preVisited = false; 322 } else { 323 forwardWalkObj = forwardWalkObj->Parent(); 324 preVisited = true; 325 walkDepth--; 326 } 327 } 328 329 return true; 330 } 331 332 template <typename T> WalkBackward(const std::shared_ptr<AstObject> & startObject,T callback)333 static bool WalkBackward(const std::shared_ptr<AstObject> &startObject, T callback) 334 { 335 std::shared_ptr<AstObject> backWalkObj = startObject; 336 std::shared_ptr<AstObject> next = nullptr; 337 std::shared_ptr<AstObject> parent = nullptr; 338 int32_t walkDepth = 0; 339 bool preVisited = false; 340 341 while (backWalkObj != nullptr) { 342 if (backWalkObj->child_ == nullptr || preVisited) { 343 next = backWalkObj->next_; 344 parent = backWalkObj->Parent(); 345 /* can safe delete current in callback */ 346 if (callback(backWalkObj, walkDepth) != NOERR) { 347 return false; 348 } 349 } else { 350 if (backWalkObj->child_) { 351 walkDepth++; 352 backWalkObj = backWalkObj->child_; 353 continue; 354 } 355 } 356 if (backWalkObj == startObject) { 357 break; 358 } 359 360 if (next != nullptr) { 361 backWalkObj = next; 362 preVisited = false; 363 } else { 364 backWalkObj = parent; 365 preVisited = true; 366 walkDepth--; 367 } 368 } 369 370 return true; 371 } 372 373 template <typename T1, typename T2> WalkRound(const std::shared_ptr<AstObject> & startObject,T1 forwardCallback,T2 backwardCallback)374 static bool WalkRound(const std::shared_ptr<AstObject> &startObject, T1 forwardCallback, T2 backwardCallback) 375 { 376 std::shared_ptr<AstObject> roundWalkObj = startObject; 377 int32_t walkDepth = 0; 378 bool preVisited = false; 379 380 while (roundWalkObj != nullptr) { 381 if (preVisited) { 382 if (backwardCallback(roundWalkObj, walkDepth) != NOERR) { 383 return false; 384 } 385 } else { 386 uint32_t ret = forwardCallback(roundWalkObj, walkDepth); 387 /* when callback return EASTWALKBREAK, not walk current's child */ 388 if (ret && ret != EASTWALKBREAK) { 389 return false; 390 } else if (!ret && roundWalkObj->child_ != nullptr) { 391 walkDepth++; 392 roundWalkObj = roundWalkObj->child_; 393 continue; 394 } 395 } 396 if (roundWalkObj == startObject) { 397 break; 398 } 399 400 if (roundWalkObj->next_) { 401 roundWalkObj = roundWalkObj->next_; 402 preVisited = false; 403 } else { 404 roundWalkObj = roundWalkObj->Parent(); 405 preVisited = true; 406 walkDepth--; 407 } 408 } 409 410 return true; 411 } 412 413 template <typename T> WalkForward(T callback)414 bool WalkForward(T callback) 415 { 416 return WalkForward(astRoot_, callback); 417 } 418 419 template <typename T> WalkBackward(T callback)420 bool WalkBackward(T callback) 421 { 422 return WalkBackward(astRoot_, callback); 423 } 424 425 template <typename T1, typename T2> WalkRound(T1 forwardCallback,T2 backwardCallback)426 bool WalkRound(T1 forwardCallback, T2 backwardCallback) 427 { 428 return WalkRound(astRoot_, forwardCallback, backwardCallback); 429 } 430 431 void Dump(const std::string &prefix = std::string()); 432 433 private: 434 bool RedefineCheck(); 435 436 bool NodeExpand(); 437 438 bool NodeExpandRef(); 439 440 bool NodeExpandDelete(); 441 442 bool NodeExpandTermRef(); 443 444 bool InheritExpand(); 445 446 static std::list<std::string> SplitNodePath(const std::string &path, char separator); 447 448 std::shared_ptr<AstObject> astRoot_; 449 bool redefineChecked_; 450 }; 451 452 std::ostream &operator<<(std::ostream &stream, const AstObject &t); 453 std::ostream &operator<<(std::ostream &stream, const ConfigNode &t); 454 std::ostream &operator<<(std::ostream &stream, const ConfigTerm &t); 455 } // namespace Hardware 456 } // namespace OHOS 457 458 #endif // HC_GEN_AST_H 459