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() const53         std::string GetMessage() const
54         {
55             return msg_;
56         }
57 
GetType() const58         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) const91     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) const108     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) const118     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() const128     const std::unordered_set<std::string> &GetBoolAttributes() const
129     {
130         return set_attributes_;
131     }
132 
GetAttributes() const133     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) const181     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() const196     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 
DeleteAnnotationElementByName(std::string_view annotation_name, std::string_view annotation_elem_name)211     void DeleteAnnotationElementByName(std::string_view annotation_name, std::string_view annotation_elem_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             annotation_iter->DeleteAnnotationElementByName(annotation_elem_name);
219         }
220     }
221 
DeleteAnnotationByName(const std::string_view &annotation_name)222     void DeleteAnnotationByName(const std::string_view &annotation_name)
223     {
224         auto annotation_iter = std::find_if(annotations_.begin(), annotations_.end(),
225             [&](pandasm::AnnotationData &annotation) -> bool {
226             return annotation.GetName() == annotation_name;
227         });
228         if (annotation_iter != annotations_.end()) {
229             (void)annotations_.erase(annotation_iter);
230         }
231     }
232 
AddAnnotationElementByName(const std::string_view &annotation_name, AnnotationElement &&element)233     void AddAnnotationElementByName(const std::string_view &annotation_name, AnnotationElement &&element)
234     {
235         auto annotation_iter = std::find_if(annotations_.begin(), annotations_.end(),
236             [&](pandasm::AnnotationData &annotation) -> bool {
237             return annotation.GetName() == annotation_name;
238         });
239         if (annotation_iter != annotations_.end()) {
240             annotation_iter->AddElement(std::move(element));
241         }
242     }
243 
SetOrAddAnnotationElementByIndex(size_t anno_idx, size_t ele_idx, AnnotationElement &&element)244     void SetOrAddAnnotationElementByIndex(size_t anno_idx, size_t ele_idx, AnnotationElement &&element)
245     {
246         ASSERT(anno_idx < annotations_.size());
247         annotations_[anno_idx].SetOrAddElementByIndex(ele_idx, std::forward<AnnotationElement>(element));
248     }
249 
250     std::optional<Error> ValidateData() override;
251 
252 protected:
253     std::optional<Error> Store(const std::string_view &attribute) override;
254 
255     std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value) override;
256 
257     virtual bool IsAnnotationRecordAttribute([[maybe_unused]] const std::string_view &attribute) const
258     {
259         return false;
260     }
261 
262     virtual bool IsAnnotationIdAttribute([[maybe_unused]] const std::string_view &attribute) const
263     {
264         return false;
265     }
266 
267     virtual bool IsAnnotationElementTypeAttribute([[maybe_unused]] const std::string_view &attribute) const
268     {
269         return false;
270     }
271 
272     virtual bool IsAnnotationElementArrayComponentTypeAttribute(
273         [[maybe_unused]] const std::string_view &attribute) const
274     {
275         return false;
276     }
277 
278     virtual bool IsAnnotationElementNameAttribute([[maybe_unused]] const std::string_view &attribute) const
279     {
280         return false;
281     }
282 
283     virtual bool IsAnnotationElementValueAttribute([[maybe_unused]] const std::string_view &attribute) const
284     {
285         return false;
286     }
287 
288 private:
289     class AnnotationElementBuilder {
290     public:
291         void Initialize(const std::string_view &name)
292         {
293             name_ = name;
294             is_initialized_ = true;
295         }
296 
297         void Reset()
298         {
299             name_.clear();
300             values_.clear();
301             type_ = {};
302             component_type_ = {};
303             is_initialized_ = false;
304         }
305 
306         void SetType(Value::Type type)
307         {
308             type_ = type;
309         }
310 
311         void SetComponentType(Value::Type type)
312         {
313             ASSERT(type != Value::Type::ARRAY);
314             component_type_ = type;
315         }
316 
317         std::optional<Error> AddValue(
318             const std::string_view &value,
319             const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotation_id_map);
320 
321         AnnotationElement CreateAnnotationElement()
322         {
323             if (IsArray()) {
324                 return AnnotationElement(name_,
325                                          std::make_unique<ArrayValue>(component_type_.value(), std::move(values_)));
326             }
327 
328             return AnnotationElement(name_, std::make_unique<ScalarValue>(values_.front()));
329         }
330 
331         bool IsArray() const
332         {
333             return type_.value() == Value::Type::ARRAY;
334         }
335 
336         bool IsTypeSet() const
337         {
338             return type_.has_value();
339         }
340 
341         bool IsComponentTypeSet() const
342         {
343             return component_type_.has_value();
344         }
345 
346         bool IsInitialized() const
347         {
348             return is_initialized_;
349         }
350 
351         bool IsCompleted() const
352         {
353             if (!IsTypeSet()) {
354                 return false;
355             }
356 
357             if (IsArray() && !IsComponentTypeSet()) {
358                 return false;
359             }
360 
361             if (!IsArray() && values_.empty()) {
362                 return false;
363             }
364 
365             return true;
366         }
367 
368     private:
369         bool is_initialized_ {false};
370         std::string name_;
371         std::optional<Value::Type> type_;
372         std::optional<Value::Type> component_type_;
373         std::vector<ScalarValue> values_;
374     };
375 
376     class AnnotationBuilder {
377     public:
378         void Initialize(const std::string_view &name)
379         {
380             name_ = name;
381             is_initialized_ = true;
382         }
383 
384         void Reset()
385         {
386             name_.clear();
387             elements_.clear();
388             id_ = {};
389             is_initialized_ = false;
390         }
391 
392         void SetId(const std::string_view &id)
393         {
394             id_ = id;
395         }
396 
397         std::string GetId() const
398         {
399             ASSERT(HasId());
400             return id_.value();
401         }
402 
403         void AddElement(AnnotationElement &&element)
404         {
405             elements_.push_back(std::forward<AnnotationElement>(element));
406         }
407 
408         std::unique_ptr<AnnotationData> CreateAnnotationData()
409         {
410             return std::make_unique<AnnotationData>(name_, std::move(elements_));
411         };
412 
413         void AddAnnnotationDataToVector(std::vector<AnnotationData> *annotations)
414         {
415             annotations->emplace_back(name_, std::move(elements_));
416         }
417 
HasId() const418         bool HasId() const
419         {
420             return id_.has_value();
421         }
422 
IsInitialized() const423         bool IsInitialized() const
424         {
425             return is_initialized_;
426         }
427 
428     private:
429         std::string name_;
430         std::optional<std::string> id_;
431         std::vector<AnnotationElement> elements_;
432         bool is_initialized_ {false};
433     };
434 
435     std::optional<Metadata::Error> MeetExpRecordAttribute(const std::string_view &attribute,
436                                                           const std::string_view &value);
437     std::optional<Metadata::Error> MeetExpIdAttribute(const std::string_view &attribute, const std::string_view &value);
438     std::optional<Metadata::Error> MeetExpElementNameAttribute(const std::string_view &attribute,
439                                                                const std::string_view &value);
440     std::optional<Metadata::Error> MeetExpElementTypeAttribute(const std::string_view &attribute,
441                                                                const std::string_view &value);
442     std::optional<Metadata::Error> MeetExpElementArrayComponentTypeAttribute(const std::string_view &attribute,
443                                                                              const std::string_view &value);
444     std::optional<Metadata::Error> MeetExpElementValueAttribute(const std::string_view &attribute,
445                                                                 const std::string_view &value);
446 
InitializeAnnotationBuilder(const std::string_view &name)447     void InitializeAnnotationBuilder(const std::string_view &name)
448     {
449         if (IsParseAnnotation()) {
450             ResetAnnotationBuilder();
451         }
452 
453         annotation_builder_.Initialize(name);
454     }
455 
ResetAnnotationBuilder()456     void ResetAnnotationBuilder()
457     {
458         ASSERT(IsParseAnnotation());
459 
460         if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
461             ResetAnnotationElementBuilder();
462         }
463 
464         if (annotation_builder_.HasId()) {
465             id_map_.insert({annotation_builder_.GetId(), annotation_builder_.CreateAnnotationData()});
466         } else {
467             annotation_builder_.AddAnnnotationDataToVector(&annotations_);
468         }
469 
470         annotation_builder_.Reset();
471     }
472 
IsParseAnnotation() const473     bool IsParseAnnotation() const
474     {
475         return annotation_builder_.IsInitialized();
476     }
477 
InitializeAnnotationElementBuilder(const std::string_view &name)478     void InitializeAnnotationElementBuilder(const std::string_view &name)
479     {
480         if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
481             ResetAnnotationElementBuilder();
482         }
483 
484         annotation_element_builder_.Initialize(name);
485     }
486 
ResetAnnotationElementBuilder()487     void ResetAnnotationElementBuilder()
488     {
489         ASSERT(IsParseAnnotationElement());
490         ASSERT(annotation_element_builder_.IsCompleted());
491 
492         annotation_builder_.AddElement(annotation_element_builder_.CreateAnnotationElement());
493 
494         annotation_element_builder_.Reset();
495     }
496 
IsParseAnnotationElement() const497     bool IsParseAnnotationElement() const
498     {
499         return annotation_element_builder_.IsInitialized();
500     }
501 
502     AnnotationBuilder annotation_builder_;
503     AnnotationElementBuilder annotation_element_builder_;
504     std::vector<AnnotationData> annotations_;
505     std::unordered_map<std::string, std::unique_ptr<AnnotationData>> id_map_;
506 };
507 
508 class ItemMetadata : public AnnotationMetadata {
509 public:
GetAccessFlags() const510     uint32_t GetAccessFlags() const
511     {
512         return access_flags_;
513     }
514 
SetAccessFlags(uint32_t access_flags)515     void SetAccessFlags(uint32_t access_flags)
516     {
517         access_flags_ = access_flags;
518     }
519 
AddAccessFlags(uint32_t access_flags)520     void AddAccessFlags(uint32_t access_flags)
521     {
522         access_flags_ = access_flags_ | access_flags;
523     }
524 
525     bool IsForeign() const;
526 
527 private:
528     uint32_t access_flags_ {0};
529 };
530 
531 class RecordMetadata : public ItemMetadata {
532 public:
533     virtual std::string GetBase() const;
534 
535     virtual std::vector<std::string> GetInterfaces() const;
536 
537     virtual bool IsAnnotation() const;
538 
539     virtual bool IsRuntimeAnnotation() const;
540 
541     virtual bool IsTypeAnnotation() const;
542 
543     virtual bool IsRuntimeTypeAnnotation() const;
544 
545 protected:
546     std::optional<Error> Validate(const std::string_view &attribute) const override;
547 
548     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
549 
550     void SetFlags(const std::string_view &attribute) override;
551 
552     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
553 
554     void RemoveFlags(const std::string_view &attribute) override;
555 
556     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
557 };
558 
559 class FieldMetadata : public ItemMetadata {
560 public:
SetFieldType(const Type &type)561     void SetFieldType(const Type &type)
562     {
563         field_type_ = type;
564     }
565 
GetFieldType() const566     Type GetFieldType() const
567     {
568         return field_type_;
569     }
570 
SetValue(const ScalarValue &value)571     void SetValue(const ScalarValue &value)
572     {
573         value_ = value;
574     }
575 
GetValue() const576     std::optional<ScalarValue> GetValue() const
577     {
578         return value_;
579     }
580 
581 protected:
582     std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value) override;
583 
584     std::optional<Error> Validate(const std::string_view &attribute) const override;
585 
586     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
587 
588     void SetFlags(const std::string_view &attribute) override;
589 
590     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
591 
592     void RemoveFlags(const std::string_view &attribute) override;
593 
594     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
595 
IsValueAttribute(const std::string_view &attribute)596     virtual bool IsValueAttribute(const std::string_view &attribute)
597     {
598         return attribute == "value";
599     }
600 
601 private:
602     Type field_type_;
603     std::optional<ScalarValue> value_;
604 };
605 
606 class FunctionMetadata : public ItemMetadata {
607 public:
608     virtual bool IsCtor() const;
609 
610     virtual bool IsCctor() const;
611 
612 protected:
613     std::optional<Error> Validate(const std::string_view &attribute) const override;
614 
615     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
616 
617     void SetFlags(const std::string_view &attribute) override;
618 
619     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
620 
621     void RemoveFlags(const std::string_view &attribute) override;
622 
623     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
624 };
625 
626 class ParamMetadata : public AnnotationMetadata {
627 protected:
628     std::optional<Error> Validate(const std::string_view &attribute) const override;
629 
630     std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
631 
632     void SetFlags(const std::string_view &attribute) override;
633 
634     void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
635 
636     void RemoveFlags(const std::string_view &attribute) override;
637 
638     void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
639 };
640 
641 }  // namespace panda::pandasm
642 
643 #endif  // ASSEMBLER_META_H
644