xref: /arkcompiler/runtime_core/assembler/meta.h (revision b1994897)
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
32namespace panda::pandasm {
33
34class Metadata {
35public:
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
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
53        std::string GetMessage() const
54        {
55            return msg_;
56        }
57
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
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
84    void RemoveAttribute(const std::string &attribute)
85    {
86        RemoveFlags(attribute);
87
88        set_attributes_.erase(attribute);
89    }
90
91    bool GetAttribute(const std::string &attribute) const
92    {
93        return set_attributes_.find(attribute) != set_attributes_.cend();
94    }
95
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
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
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
128    const std::unordered_set<std::string> &GetBoolAttributes() const
129    {
130        return set_attributes_;
131    }
132
133    const std::unordered_map<std::string, std::vector<std::string>> &GetAttributes() const
134    {
135        return attributes_;
136    }
137
138    virtual std::optional<Error> ValidateData()
139    {
140        return {};
141    }
142
143    DEFAULT_COPY_SEMANTIC(Metadata);
144
145    DEFAULT_MOVE_SEMANTIC(Metadata);
146
147protected:
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
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
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
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
189private:
190    std::unordered_set<std::string> set_attributes_;
191    std::unordered_map<std::string, std::vector<std::string>> attributes_;
192};
193
194class AnnotationMetadata : public Metadata {
195public:
196    const std::vector<AnnotationData> &GetAnnotations() const
197    {
198        return annotations_;
199    }
200
201    void SetAnnotations(std::vector<AnnotationData> &&annotations)
202    {
203        annotations_ = std::forward<std::vector<AnnotationData>>(annotations);
204    }
205
206    void AddAnnotations(const std::vector<AnnotationData> &annotations)
207    {
208        annotations_.insert(annotations_.end(), annotations.begin(), annotations.end());
209    }
210
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
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
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
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
252protected:
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
288private:
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
418        bool HasId() const
419        {
420            return id_.has_value();
421        }
422
423        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
447    void InitializeAnnotationBuilder(const std::string_view &name)
448    {
449        if (IsParseAnnotation()) {
450            ResetAnnotationBuilder();
451        }
452
453        annotation_builder_.Initialize(name);
454    }
455
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
473    bool IsParseAnnotation() const
474    {
475        return annotation_builder_.IsInitialized();
476    }
477
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
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
497    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
508class ItemMetadata : public AnnotationMetadata {
509public:
510    uint32_t GetAccessFlags() const
511    {
512        return access_flags_;
513    }
514
515    void SetAccessFlags(uint32_t access_flags)
516    {
517        access_flags_ = access_flags;
518    }
519
520    void AddAccessFlags(uint32_t access_flags)
521    {
522        access_flags_ = access_flags_ | access_flags;
523    }
524
525    bool IsForeign() const;
526
527private:
528    uint32_t access_flags_ {0};
529};
530
531class RecordMetadata : public ItemMetadata {
532public:
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
545protected:
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
559class FieldMetadata : public ItemMetadata {
560public:
561    void SetFieldType(const Type &type)
562    {
563        field_type_ = type;
564    }
565
566    Type GetFieldType() const
567    {
568        return field_type_;
569    }
570
571    void SetValue(const ScalarValue &value)
572    {
573        value_ = value;
574    }
575
576    std::optional<ScalarValue> GetValue() const
577    {
578        return value_;
579    }
580
581protected:
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
596    virtual bool IsValueAttribute(const std::string_view &attribute)
597    {
598        return attribute == "value";
599    }
600
601private:
602    Type field_type_;
603    std::optional<ScalarValue> value_;
604};
605
606class FunctionMetadata : public ItemMetadata {
607public:
608    virtual bool IsCtor() const;
609
610    virtual bool IsCctor() const;
611
612protected:
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
626class ParamMetadata : public AnnotationMetadata {
627protected:
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