• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 
16 #ifndef ASSEMBLER_META_H
17 #define ASSEMBLER_META_H
18 
19 #include <memory>
20 #include <stack>
21 #include <tuple>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <variant>
25 #include <vector>
26 
27 #include "annotation.h"
28 #include "modifiers.h"
29 
30 #include "assembly-type.h"
31 
32 namespace panda::pandasm {
33 
34 class Metadata {
35 public:
36     class Error {
37     public:
38         enum class Type {
39             INVALID_VALUE,
40             MISSING_ATTRIBUTE,
41             MISSING_VALUE,
42             MULTIPLE_ATTRIBUTE,
43             UNEXPECTED_ATTRIBUTE,
44             UNEXPECTED_VALUE,
45             UNKNOWN_ATTRIBUTE
46         };
47 
Error(std::string msg,Type type)48         Error(std::string msg, Type type) : msg_(std::move(msg)), type_(type) {}
49         ~Error() = default;
50         DEFAULT_MOVE_SEMANTIC(Error);
51         DEFAULT_COPY_SEMANTIC(Error);
52 
GetMessage()53         std::string GetMessage() const
54         {
55             return msg_;
56         }
57 
GetType()58         Type GetType() const
59         {
60             return type_;
61         }
62 
63     private:
64         std::string msg_;
65         Type type_;
66     };
67 
68     Metadata() = default;
69 
70     virtual ~Metadata() = default;
71 
SetAttribute(const std::string_view & attribute)72     std::optional<Error> SetAttribute(const std::string_view &attribute)
73     {
74         auto err = Validate(attribute);
75         if (err) {
76             return err;
77         }
78 
79         SetFlags(attribute);
80 
81         return Store(attribute);
82     }
83 
RemoveAttribute(const std::string & attribute)84     void RemoveAttribute(const std::string &attribute)
85     {
86         RemoveFlags(attribute);
87 
88         set_attributes_.erase(attribute);
89     }
90 
GetAttribute(const std::string & attribute)91     bool GetAttribute(const std::string &attribute) const
92     {
93         return set_attributes_.find(attribute) != set_attributes_.cend();
94     }
95 
SetAttributeValue(const std::string_view & attribute,const std::string_view & value)96     std::optional<Error> SetAttributeValue(const std::string_view &attribute, const std::string_view &value)
97     {
98         auto err = Validate(attribute, value);
99         if (err) {
100             return err;
101         }
102 
103         SetFlags(attribute, value);
104 
105         return StoreValue(attribute, value);
106     }
107 
GetAttributeValues(const std::string & attribute)108     std::vector<std::string> GetAttributeValues(const std::string &attribute) const
109     {
110         auto it = attributes_.find(attribute);
111         if (it == attributes_.cend()) {
112             return {};
113         }
114 
115         return it->second;
116     }
117 
GetAttributeValue(const std::string & attribute)118     std::optional<std::string> GetAttributeValue(const std::string &attribute) const
119     {
120         auto values = GetAttributeValues(attribute);
121         if (!values.empty()) {
122             return values.front();
123         }
124 
125         return {};
126     }
127 
GetBoolAttributes()128     const std::unordered_set<std::string> &GetBoolAttributes() const
129     {
130         return set_attributes_;
131     }
132 
GetAttributes()133     const std::unordered_map<std::string, std::vector<std::string>> &GetAttributes() const
134     {
135         return attributes_;
136     }
137 
ValidateData()138     virtual std::optional<Error> ValidateData()
139     {
140         return {};
141     }
142 
143     DEFAULT_COPY_SEMANTIC(Metadata);
144 
145     DEFAULT_MOVE_SEMANTIC(Metadata);
146 
147 protected:
148     virtual std::optional<Error> Validate(const std::string_view &attribute) const = 0;
149 
150     virtual std::optional<Error> Validate(const std::string_view &attribute,
151                                           const std::string_view &value) const = 0;
152 
StoreValue(const std::string_view & attribute,const std::string_view & value)153     virtual std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value)
154     {
155         std::string key(attribute);
156         auto it = attributes_.find(key);
157         if (it == attributes_.cend()) {
158             std::tie(it, std::ignore) = attributes_.try_emplace(key);
159         }
160 
161         it->second.emplace_back(value);
162 
163         return {};
164     }
165 
Store(const std::string_view & attribute)166     virtual std::optional<Error> Store(const std::string_view &attribute)
167     {
168         set_attributes_.emplace(attribute);
169 
170         return {};
171     }
172 
173     virtual void SetFlags(const std::string_view &attribute) = 0;
174 
175     virtual void SetFlags(const std::string_view &attribute, const std::string_view &value) = 0;
176 
177     virtual void RemoveFlags(const std::string_view &attribute) = 0;
178 
179     virtual void RemoveFlags(const std::string_view &attribute, const std::string_view &value) = 0;
180 
HasAttribute(const std::string_view & attribute)181     bool HasAttribute(const std::string_view &attribute) const
182     {
183         std::string key(attribute);
184         return GetAttribute(key) || GetAttributeValue(key);
185     }
186 
187     std::optional<Error> ValidateSize(const std::string_view &value) const;
188 
189 private:
190     std::unordered_set<std::string> set_attributes_;
191     std::unordered_map<std::string, std::vector<std::string>> attributes_;
192 };
193 
194 class AnnotationMetadata : public Metadata {
195 public:
GetAnnotations()196     const std::vector<AnnotationData> &GetAnnotations() const
197     {
198         return annotations_;
199     }
200 
SetAnnotations(std::vector<AnnotationData> && annotations)201     void SetAnnotations(std::vector<AnnotationData> &&annotations)
202     {
203         annotations_ = std::forward<std::vector<AnnotationData>>(annotations);
204     }
205 
AddAnnotations(const std::vector<AnnotationData> & annotations)206     void AddAnnotations(const std::vector<AnnotationData> &annotations)
207     {
208         annotations_.insert(annotations_.end(), annotations.begin(), annotations.end());
209     }
210 
DeleteAnnotationByName(const std::string_view & annotation_name)211     void DeleteAnnotationByName(const std::string_view &annotation_name)
212     {
213         auto annotation_iter = std::find_if(annotations_.begin(), annotations_.end(),
214             [&](pandasm::AnnotationData &annotation) -> bool {
215             return annotation.GetName() == annotation_name;
216         });
217         if (annotation_iter != annotations_.end()) {
218             (void)annotations_.erase(annotation_iter);
219         }
220     }
221 
SetOrAddAnnotationElementByIndex(size_t anno_idx,size_t ele_idx,AnnotationElement && element)222     void SetOrAddAnnotationElementByIndex(size_t anno_idx, size_t ele_idx, AnnotationElement &&element)
223     {
224         ASSERT(anno_idx < annotations_.size());
225         annotations_[anno_idx].SetOrAddElementByIndex(ele_idx, std::forward<AnnotationElement>(element));
226     }
227 
228     std::optional<Error> ValidateData() override;
229 
230 protected:
231     std::optional<Error> Store(const std::string_view &attribute) override;
232 
233     std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value) override;
234 
IsAnnotationRecordAttribute(const std::string_view & attribute)235     virtual bool IsAnnotationRecordAttribute([[maybe_unused]] const std::string_view &attribute) const
236     {
237         return false;
238     }
239 
IsAnnotationIdAttribute(const std::string_view & attribute)240     virtual bool IsAnnotationIdAttribute([[maybe_unused]] const std::string_view &attribute) const
241     {
242         return false;
243     }
244 
IsAnnotationElementTypeAttribute(const std::string_view & attribute)245     virtual bool IsAnnotationElementTypeAttribute([[maybe_unused]] const std::string_view &attribute) const
246     {
247         return false;
248     }
249 
IsAnnotationElementArrayComponentTypeAttribute(const std::string_view & attribute)250     virtual bool IsAnnotationElementArrayComponentTypeAttribute(
251         [[maybe_unused]] const std::string_view &attribute) const
252     {
253         return false;
254     }
255 
IsAnnotationElementNameAttribute(const std::string_view & attribute)256     virtual bool IsAnnotationElementNameAttribute([[maybe_unused]] const std::string_view &attribute) const
257     {
258         return false;
259     }
260 
IsAnnotationElementValueAttribute(const std::string_view & attribute)261     virtual bool IsAnnotationElementValueAttribute([[maybe_unused]] const std::string_view &attribute) const
262     {
263         return false;
264     }
265 
266 private:
267     class AnnotationElementBuilder {
268     public:
Initialize(const std::string_view & name)269         void Initialize(const std::string_view &name)
270         {
271             name_ = name;
272             is_initialized_ = true;
273         }
274 
Reset()275         void Reset()
276         {
277             name_.clear();
278             values_.clear();
279             type_ = {};
280             component_type_ = {};
281             is_initialized_ = false;
282         }
283 
SetType(Value::Type type)284         void SetType(Value::Type type)
285         {
286             type_ = type;
287         }
288 
SetComponentType(Value::Type type)289         void SetComponentType(Value::Type type)
290         {
291             ASSERT(type != Value::Type::ARRAY);
292             component_type_ = type;
293         }
294 
295         std::optional<Error> AddValue(
296             const std::string_view &value,
297             const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotation_id_map);
298 
CreateAnnotationElement()299         AnnotationElement CreateAnnotationElement()
300         {
301             if (IsArray()) {
302                 return AnnotationElement(name_,
303                                          std::make_unique<ArrayValue>(component_type_.value(), std::move(values_)));
304             }
305 
306             return AnnotationElement(name_, std::make_unique<ScalarValue>(values_.front()));
307         }
308 
IsArray()309         bool IsArray() const
310         {
311             return type_.value() == Value::Type::ARRAY;
312         }
313 
IsTypeSet()314         bool IsTypeSet() const
315         {
316             return type_.has_value();
317         }
318 
IsComponentTypeSet()319         bool IsComponentTypeSet() const
320         {
321             return component_type_.has_value();
322         }
323 
IsInitialized()324         bool IsInitialized() const
325         {
326             return is_initialized_;
327         }
328 
IsCompleted()329         bool IsCompleted() const
330         {
331             if (!IsTypeSet()) {
332                 return false;
333             }
334 
335             if (IsArray() && !IsComponentTypeSet()) {
336                 return false;
337             }
338 
339             if (!IsArray() && values_.empty()) {
340                 return false;
341             }
342 
343             return true;
344         }
345 
346     private:
347         bool is_initialized_ {false};
348         std::string name_;
349         std::optional<Value::Type> type_;
350         std::optional<Value::Type> component_type_;
351         std::vector<ScalarValue> values_;
352     };
353 
354     class AnnotationBuilder {
355     public:
Initialize(const std::string_view & name)356         void Initialize(const std::string_view &name)
357         {
358             name_ = name;
359             is_initialized_ = true;
360         }
361 
Reset()362         void Reset()
363         {
364             name_.clear();
365             elements_.clear();
366             id_ = {};
367             is_initialized_ = false;
368         }
369 
SetId(const std::string_view & id)370         void SetId(const std::string_view &id)
371         {
372             id_ = id;
373         }
374 
GetId()375         std::string GetId() const
376         {
377             ASSERT(HasId());
378             return id_.value();
379         }
380 
AddElement(AnnotationElement && element)381         void AddElement(AnnotationElement &&element)
382         {
383             elements_.push_back(std::forward<AnnotationElement>(element));
384         }
385 
CreateAnnotationData()386         std::unique_ptr<AnnotationData> CreateAnnotationData()
387         {
388             return std::make_unique<AnnotationData>(name_, std::move(elements_));
389         };
390 
AddAnnnotationDataToVector(std::vector<AnnotationData> * annotations)391         void AddAnnnotationDataToVector(std::vector<AnnotationData> *annotations)
392         {
393             annotations->emplace_back(name_, std::move(elements_));
394         }
395 
HasId()396         bool HasId() const
397         {
398             return id_.has_value();
399         }
400 
IsInitialized()401         bool IsInitialized() const
402         {
403             return is_initialized_;
404         }
405 
406     private:
407         std::string name_;
408         std::optional<std::string> id_;
409         std::vector<AnnotationElement> elements_;
410         bool is_initialized_ {false};
411     };
412 
413     std::optional<Metadata::Error> MeetExpRecordAttribute(const std::string_view &attribute,
414                                                           const std::string_view &value);
415     std::optional<Metadata::Error> MeetExpIdAttribute(const std::string_view &attribute, const std::string_view &value);
416     std::optional<Metadata::Error> MeetExpElementNameAttribute(const std::string_view &attribute,
417                                                                const std::string_view &value);
418     std::optional<Metadata::Error> MeetExpElementTypeAttribute(const std::string_view &attribute,
419                                                                const std::string_view &value);
420     std::optional<Metadata::Error> MeetExpElementArrayComponentTypeAttribute(const std::string_view &attribute,
421                                                                              const std::string_view &value);
422     std::optional<Metadata::Error> MeetExpElementValueAttribute(const std::string_view &attribute,
423                                                                 const std::string_view &value);
424 
InitializeAnnotationBuilder(const std::string_view & name)425     void InitializeAnnotationBuilder(const std::string_view &name)
426     {
427         if (IsParseAnnotation()) {
428             ResetAnnotationBuilder();
429         }
430 
431         annotation_builder_.Initialize(name);
432     }
433 
ResetAnnotationBuilder()434     void ResetAnnotationBuilder()
435     {
436         ASSERT(IsParseAnnotation());
437 
438         if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
439             ResetAnnotationElementBuilder();
440         }
441 
442         if (annotation_builder_.HasId()) {
443             id_map_.insert({annotation_builder_.GetId(), annotation_builder_.CreateAnnotationData()});
444         } else {
445             annotation_builder_.AddAnnnotationDataToVector(&annotations_);
446         }
447 
448         annotation_builder_.Reset();
449     }
450 
IsParseAnnotation()451     bool IsParseAnnotation() const
452     {
453         return annotation_builder_.IsInitialized();
454     }
455 
InitializeAnnotationElementBuilder(const std::string_view & name)456     void InitializeAnnotationElementBuilder(const std::string_view &name)
457     {
458         if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
459             ResetAnnotationElementBuilder();
460         }
461 
462         annotation_element_builder_.Initialize(name);
463     }
464 
ResetAnnotationElementBuilder()465     void ResetAnnotationElementBuilder()
466     {
467         ASSERT(IsParseAnnotationElement());
468         ASSERT(annotation_element_builder_.IsCompleted());
469 
470         annotation_builder_.AddElement(annotation_element_builder_.CreateAnnotationElement());
471 
472         annotation_element_builder_.Reset();
473     }
474 
IsParseAnnotationElement()475     bool IsParseAnnotationElement() const
476     {
477         return annotation_element_builder_.IsInitialized();
478     }
479 
480     AnnotationBuilder annotation_builder_;
481     AnnotationElementBuilder annotation_element_builder_;
482     std::vector<AnnotationData> annotations_;
483     std::unordered_map<std::string, std::unique_ptr<AnnotationData>> id_map_;
484 };
485 
486 class ItemMetadata : public AnnotationMetadata {
487 public:
GetAccessFlags()488     uint32_t GetAccessFlags() const
489     {
490         return access_flags_;
491     }
492 
SetAccessFlags(uint32_t access_flags)493     void SetAccessFlags(uint32_t access_flags)
494     {
495         access_flags_ = access_flags;
496     }
497 
AddAccessFlags(uint32_t access_flags)498     void AddAccessFlags(uint32_t access_flags)
499     {
500         access_flags_ = access_flags_ | access_flags;
501     }
502 
503     bool IsForeign() const;
504 
505 private:
506     uint32_t access_flags_ {0};
507 };
508 
509 class RecordMetadata : public ItemMetadata {
510 public:
511     virtual std::string GetBase() const;
512 
513     virtual std::vector<std::string> GetInterfaces() const;
514 
515     virtual bool IsAnnotation() const;
516 
517     virtual bool IsRuntimeAnnotation() const;
518 
519     virtual bool IsTypeAnnotation() const;
520 
521     virtual bool IsRuntimeTypeAnnotation() const;
522 
523 protected:
524     std::optional<Error> Validate(const std::string_view &attribute) const override;
525 
526     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
527 
528     void SetFlags(const std::string_view &attribute) override;
529 
530     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
531 
532     void RemoveFlags(const std::string_view &attribute) override;
533 
534     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
535 };
536 
537 class FieldMetadata : public ItemMetadata {
538 public:
SetFieldType(const Type & type)539     void SetFieldType(const Type &type)
540     {
541         field_type_ = type;
542     }
543 
GetFieldType()544     Type GetFieldType() const
545     {
546         return field_type_;
547     }
548 
SetValue(const ScalarValue & value)549     void SetValue(const ScalarValue &value)
550     {
551         value_ = value;
552     }
553 
GetValue()554     std::optional<ScalarValue> GetValue() const
555     {
556         return value_;
557     }
558 
559 protected:
560     std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value) override;
561 
562     std::optional<Error> Validate(const std::string_view &attribute) const override;
563 
564     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
565 
566     void SetFlags(const std::string_view &attribute) override;
567 
568     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
569 
570     void RemoveFlags(const std::string_view &attribute) override;
571 
572     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
573 
IsValueAttribute(const std::string_view & attribute)574     virtual bool IsValueAttribute(const std::string_view &attribute)
575     {
576         return attribute == "value";
577     }
578 
579 private:
580     Type field_type_;
581     std::optional<ScalarValue> value_;
582 };
583 
584 class FunctionMetadata : public ItemMetadata {
585 public:
586     virtual bool IsCtor() const;
587 
588     virtual bool IsCctor() const;
589 
590 protected:
591     std::optional<Error> Validate(const std::string_view &attribute) const override;
592 
593     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
594 
595     void SetFlags(const std::string_view &attribute) override;
596 
597     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
598 
599     void RemoveFlags(const std::string_view &attribute) override;
600 
601     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
602 };
603 
604 class ParamMetadata : public AnnotationMetadata {
605 protected:
606     std::optional<Error> Validate(const std::string_view &attribute) const override;
607 
608     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
609 
610     void SetFlags(const std::string_view &attribute) override;
611 
612     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
613 
614     void RemoveFlags(const std::string_view &attribute) override;
615 
616     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
617 };
618 
619 }  // namespace panda::pandasm
620 
621 #endif  // ASSEMBLER_META_H
622