• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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