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