• 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(std::string_view attribute)72     std::optional<Error> SetAttribute(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(std::string_view attribute,std::string_view value)96     std::optional<Error> SetAttributeValue(std::string_view attribute, 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 
122         if (!values.empty()) {
123             return values.front();
124         }
125 
126         return {};
127     }
128 
GetBoolAttributes()129     const std::unordered_set<std::string> &GetBoolAttributes() const
130     {
131         return set_attributes_;
132     }
133 
GetAttributes()134     const std::unordered_map<std::string, std::vector<std::string>> &GetAttributes() const
135     {
136         return attributes_;
137     }
138 
ValidateData()139     virtual std::optional<Error> ValidateData()
140     {
141         return {};
142     }
143 
144     DEFAULT_COPY_SEMANTIC(Metadata);
145 
146     DEFAULT_MOVE_SEMANTIC(Metadata);
147 
148 protected:
149     virtual std::optional<Error> Validate(std::string_view attribute) const = 0;
150 
151     virtual std::optional<Error> Validate(std::string_view attribute, std::string_view value) const = 0;
152 
StoreValue(std::string_view attribute,std::string_view value)153     virtual std::optional<Error> StoreValue(std::string_view attribute, 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(std::string_view attribute)166     virtual std::optional<Error> Store(std::string_view attribute)
167     {
168         set_attributes_.emplace(attribute);
169 
170         return {};
171     }
172 
173     virtual void SetFlags(std::string_view attribute) = 0;
174 
175     virtual void SetFlags(std::string_view attribute, std::string_view value) = 0;
176 
177     virtual void RemoveFlags(std::string_view attribute) = 0;
178 
179     virtual void RemoveFlags(std::string_view attribute, std::string_view value) = 0;
180 
HasAttribute(std::string_view attribute)181     bool HasAttribute(std::string_view attribute) const
182     {
183         std::string key(attribute);
184         return GetAttribute(key) || GetAttributeValue(key);
185     }
186 
187     std::optional<Error> ValidateSize(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 
SetOrAddAnnotationElementByIndex(size_t anno_idx,size_t ele_idx,AnnotationElement && element)211     void SetOrAddAnnotationElementByIndex(size_t anno_idx, size_t ele_idx, AnnotationElement &&element)
212     {
213         ASSERT(anno_idx < annotations_.size());
214         annotations_[anno_idx].SetOrAddElementByIndex(ele_idx, std::forward<AnnotationElement>(element));
215     }
216 
217     std::optional<Error> ValidateData() override;
218 
219 protected:
220     std::optional<Error> Store(std::string_view attribute) override;
221 
222     std::optional<Error> StoreValue(std::string_view attribute, std::string_view value) override;
223 
IsAnnotationRecordAttribute(std::string_view attribute)224     virtual bool IsAnnotationRecordAttribute([[maybe_unused]] std::string_view attribute) const
225     {
226         return false;
227     }
228 
IsAnnotationIdAttribute(std::string_view attribute)229     virtual bool IsAnnotationIdAttribute([[maybe_unused]] std::string_view attribute) const
230     {
231         return false;
232     }
233 
IsAnnotationElementTypeAttribute(std::string_view attribute)234     virtual bool IsAnnotationElementTypeAttribute([[maybe_unused]] std::string_view attribute) const
235     {
236         return false;
237     }
238 
IsAnnotationElementArrayComponentTypeAttribute(std::string_view attribute)239     virtual bool IsAnnotationElementArrayComponentTypeAttribute([[maybe_unused]] std::string_view attribute) const
240     {
241         return false;
242     }
243 
IsAnnotationElementNameAttribute(std::string_view attribute)244     virtual bool IsAnnotationElementNameAttribute([[maybe_unused]] std::string_view attribute) const
245     {
246         return false;
247     }
248 
IsAnnotationElementValueAttribute(std::string_view attribute)249     virtual bool IsAnnotationElementValueAttribute([[maybe_unused]] std::string_view attribute) const
250     {
251         return false;
252     }
253 
254 private:
255     class AnnotationElementBuilder {
256     public:
Initialize(std::string_view name)257         void Initialize(std::string_view name)
258         {
259             name_ = name;
260             is_initialized_ = true;
261         }
262 
Reset()263         void Reset()
264         {
265             name_.clear();
266             values_.clear();
267             type_ = {};
268             component_type_ = {};
269             is_initialized_ = false;
270         }
271 
SetType(Value::Type type)272         void SetType(Value::Type type)
273         {
274             type_ = type;
275         }
276 
SetComponentType(Value::Type type)277         void SetComponentType(Value::Type type)
278         {
279             ASSERT(type != Value::Type::ARRAY);
280             component_type_ = type;
281         }
282 
283         std::optional<Error> AddValue(
284             std::string_view value,
285             const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotation_id_map);
286 
CreateAnnotationElement()287         AnnotationElement CreateAnnotationElement()
288         {
289             if (IsArray()) {
290                 return AnnotationElement(name_,
291                                          std::make_unique<ArrayValue>(component_type_.value(), std::move(values_)));
292             }
293 
294             return AnnotationElement(name_, std::make_unique<ScalarValue>(values_.front()));
295         }
296 
IsArray()297         bool IsArray() const
298         {
299             return type_.value() == Value::Type::ARRAY;
300         }
301 
IsTypeSet()302         bool IsTypeSet() const
303         {
304             return type_.has_value();
305         }
306 
IsComponentTypeSet()307         bool IsComponentTypeSet() const
308         {
309             return component_type_.has_value();
310         }
311 
IsInitialized()312         bool IsInitialized() const
313         {
314             return is_initialized_;
315         }
316 
IsCompleted()317         bool IsCompleted() const
318         {
319             if (!IsTypeSet()) {
320                 return false;
321             }
322 
323             if (IsArray() && !IsComponentTypeSet()) {
324                 return false;
325             }
326 
327             if (!IsArray() && values_.empty()) {
328                 return false;
329             }
330 
331             return true;
332         }
333 
334     private:
335         bool is_initialized_ {false};
336         std::string name_;
337         std::optional<Value::Type> type_;
338         std::optional<Value::Type> component_type_;
339         std::vector<ScalarValue> values_;
340     };
341 
342     class AnnotationBuilder {
343     public:
Initialize(std::string_view name)344         void Initialize(std::string_view name)
345         {
346             name_ = name;
347             is_initialized_ = true;
348         }
349 
Reset()350         void Reset()
351         {
352             name_.clear();
353             elements_.clear();
354             id_ = {};
355             is_initialized_ = false;
356         }
357 
SetId(std::string_view id)358         void SetId(std::string_view id)
359         {
360             id_ = id;
361         }
362 
GetId()363         std::string GetId() const
364         {
365             ASSERT(HasId());
366             return id_.value();
367         }
368 
AddElement(AnnotationElement && element)369         void AddElement(AnnotationElement &&element)
370         {
371             elements_.push_back(std::forward<AnnotationElement>(element));
372         }
373 
CreateAnnotationData()374         std::unique_ptr<AnnotationData> CreateAnnotationData()
375         {
376             return std::make_unique<AnnotationData>(name_, std::move(elements_));
377         };
378 
AddAnnnotationDataToVector(std::vector<AnnotationData> * annotations)379         void AddAnnnotationDataToVector(std::vector<AnnotationData> *annotations)
380         {
381             annotations->emplace_back(name_, std::move(elements_));
382         }
383 
HasId()384         bool HasId() const
385         {
386             return id_.has_value();
387         }
388 
IsInitialized()389         bool IsInitialized() const
390         {
391             return is_initialized_;
392         }
393 
394     private:
395         std::string name_;
396         std::optional<std::string> id_;
397         std::vector<AnnotationElement> elements_;
398         bool is_initialized_ {false};
399     };
400 
401     std::optional<Metadata::Error> MeetExpRecordAttribute(std::string_view attribute, std::string_view value);
402     std::optional<Metadata::Error> MeetExpIdAttribute(std::string_view attribute, std::string_view value);
403     std::optional<Metadata::Error> MeetExpElementNameAttribute(std::string_view attribute, std::string_view value);
404     std::optional<Metadata::Error> MeetExpElementTypeAttribute(std::string_view attribute, std::string_view value);
405     std::optional<Metadata::Error> MeetExpElementArrayComponentTypeAttribute(std::string_view attribute,
406                                                                              std::string_view value);
407     std::optional<Metadata::Error> MeetExpElementValueAttribute(std::string_view attribute, std::string_view value);
408 
InitializeAnnotationBuilder(std::string_view name)409     void InitializeAnnotationBuilder(std::string_view name)
410     {
411         if (IsParseAnnotation()) {
412             ResetAnnotationBuilder();
413         }
414 
415         annotation_builder_.Initialize(name);
416     }
417 
ResetAnnotationBuilder()418     void ResetAnnotationBuilder()
419     {
420         ASSERT(IsParseAnnotation());
421 
422         if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
423             ResetAnnotationElementBuilder();
424         }
425 
426         if (annotation_builder_.HasId()) {
427             id_map_.insert({annotation_builder_.GetId(), annotation_builder_.CreateAnnotationData()});
428         } else {
429             annotation_builder_.AddAnnnotationDataToVector(&annotations_);
430         }
431 
432         annotation_builder_.Reset();
433     }
434 
IsParseAnnotation()435     bool IsParseAnnotation() const
436     {
437         return annotation_builder_.IsInitialized();
438     }
439 
InitializeAnnotationElementBuilder(std::string_view name)440     void InitializeAnnotationElementBuilder(std::string_view name)
441     {
442         if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
443             ResetAnnotationElementBuilder();
444         }
445 
446         annotation_element_builder_.Initialize(name);
447     }
448 
ResetAnnotationElementBuilder()449     void ResetAnnotationElementBuilder()
450     {
451         ASSERT(IsParseAnnotationElement());
452         ASSERT(annotation_element_builder_.IsCompleted());
453 
454         annotation_builder_.AddElement(annotation_element_builder_.CreateAnnotationElement());
455 
456         annotation_element_builder_.Reset();
457     }
458 
IsParseAnnotationElement()459     bool IsParseAnnotationElement() const
460     {
461         return annotation_element_builder_.IsInitialized();
462     }
463 
464     AnnotationBuilder annotation_builder_;
465     AnnotationElementBuilder annotation_element_builder_;
466     std::vector<AnnotationData> annotations_;
467     std::unordered_map<std::string, std::unique_ptr<AnnotationData>> id_map_;
468 };
469 
470 class ItemMetadata : public AnnotationMetadata {
471 public:
GetAccessFlags()472     uint32_t GetAccessFlags() const
473     {
474         return access_flags_;
475     }
476 
SetAccessFlags(uint32_t access_flags)477     void SetAccessFlags(uint32_t access_flags)
478     {
479         access_flags_ = access_flags;
480     }
481 
482     bool IsForeign() const;
483 
484 private:
485     uint32_t access_flags_ {0};
486 };
487 
488 class RecordMetadata : public ItemMetadata {
489 public:
490     virtual std::string GetBase() const;
491 
492     virtual std::vector<std::string> GetInterfaces() const;
493 
494     virtual bool IsAnnotation() const;
495 
496     virtual bool IsRuntimeAnnotation() const;
497 
498     virtual bool IsTypeAnnotation() const;
499 
500     virtual bool IsRuntimeTypeAnnotation() const;
501 
502 protected:
503     std::optional<Error> Validate(std::string_view attribute) const override;
504 
505     std::optional<Error> Validate(std::string_view attribute, std::string_view value) const override;
506 
507     void SetFlags(std::string_view attribute) override;
508 
509     void SetFlags(std::string_view attribute, std::string_view value) override;
510 
511     void RemoveFlags(std::string_view attribute) override;
512 
513     void RemoveFlags(std::string_view attribute, std::string_view value) override;
514 };
515 
516 class FieldMetadata : public ItemMetadata {
517 public:
SetFieldType(const Type & type)518     void SetFieldType(const Type &type)
519     {
520         field_type_ = type;
521     }
522 
GetFieldType()523     Type GetFieldType() const
524     {
525         return field_type_;
526     }
527 
SetValue(const ScalarValue & value)528     void SetValue(const ScalarValue &value)
529     {
530         value_ = value;
531     }
532 
GetValue()533     std::optional<ScalarValue> GetValue() const
534     {
535         return value_;
536     }
537 
538 protected:
539     std::optional<Error> StoreValue(std::string_view attribute, std::string_view value) override;
540 
541     std::optional<Error> Validate(std::string_view attribute) const override;
542 
543     std::optional<Error> Validate(std::string_view attribute, std::string_view value) const override;
544 
545     void SetFlags(std::string_view attribute) override;
546 
547     void SetFlags(std::string_view attribute, std::string_view value) override;
548 
549     void RemoveFlags(std::string_view attribute) override;
550 
551     void RemoveFlags(std::string_view attribute, std::string_view value) override;
552 
IsValueAttribute(std::string_view attribute)553     virtual bool IsValueAttribute(std::string_view attribute)
554     {
555         return attribute == "value";
556     }
557 
558 private:
559     Type field_type_;
560     std::optional<ScalarValue> value_;
561 };
562 
563 class FunctionMetadata : public ItemMetadata {
564 public:
565     virtual bool IsCtor() const;
566 
567     virtual bool IsCctor() const;
568 
569 protected:
570     std::optional<Error> Validate(std::string_view attribute) const override;
571 
572     std::optional<Error> Validate(std::string_view attribute, std::string_view value) const override;
573 
574     void SetFlags(std::string_view attribute) override;
575 
576     void SetFlags(std::string_view attribute, std::string_view value) override;
577 
578     void RemoveFlags(std::string_view attribute) override;
579 
580     void RemoveFlags(std::string_view attribute, std::string_view value) override;
581 };
582 
583 class ParamMetadata : public AnnotationMetadata {
584 protected:
585     std::optional<Error> Validate(std::string_view attribute) const override;
586 
587     std::optional<Error> Validate(std::string_view attribute, std::string_view value) const override;
588 
589     void SetFlags(std::string_view attribute) override;
590 
591     void SetFlags(std::string_view attribute, std::string_view value) override;
592 
593     void RemoveFlags(std::string_view attribute) override;
594 
595     void RemoveFlags(std::string_view attribute, std::string_view value) override;
596 };
597 
598 }  // namespace panda::pandasm
599 
600 #endif  // ASSEMBLER_META_H
601