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