Nazarov Konstantin 97385e96aa Support add/delete annotation elements
Issue: #IAS8XN

Signed-off-by: Nazarov Konstantin <nazarov.konstantin@huawei.com>
Change-Id: I27fad211bc40a469505b19bbea60df1861f6cca6
2024-09-20 20:39:58 +08:00

644 lines
18 KiB
C++

/**
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ASSEMBLER_META_H
#define ASSEMBLER_META_H
#include <memory>
#include <stack>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include <vector>
#include "annotation.h"
#include "modifiers.h"
#include "assembly-type.h"
namespace panda::pandasm {
class Metadata {
public:
class Error {
public:
enum class Type {
INVALID_VALUE,
MISSING_ATTRIBUTE,
MISSING_VALUE,
MULTIPLE_ATTRIBUTE,
UNEXPECTED_ATTRIBUTE,
UNEXPECTED_VALUE,
UNKNOWN_ATTRIBUTE
};
Error(std::string msg, Type type) : msg_(std::move(msg)), type_(type) {}
~Error() = default;
DEFAULT_MOVE_SEMANTIC(Error);
DEFAULT_COPY_SEMANTIC(Error);
std::string GetMessage() const
{
return msg_;
}
Type GetType() const
{
return type_;
}
private:
std::string msg_;
Type type_;
};
Metadata() = default;
virtual ~Metadata() = default;
std::optional<Error> SetAttribute(const std::string_view &attribute)
{
auto err = Validate(attribute);
if (err) {
return err;
}
SetFlags(attribute);
return Store(attribute);
}
void RemoveAttribute(const std::string &attribute)
{
RemoveFlags(attribute);
set_attributes_.erase(attribute);
}
bool GetAttribute(const std::string &attribute) const
{
return set_attributes_.find(attribute) != set_attributes_.cend();
}
std::optional<Error> SetAttributeValue(const std::string_view &attribute, const std::string_view &value)
{
auto err = Validate(attribute, value);
if (err) {
return err;
}
SetFlags(attribute, value);
return StoreValue(attribute, value);
}
std::vector<std::string> GetAttributeValues(const std::string &attribute) const
{
auto it = attributes_.find(attribute);
if (it == attributes_.cend()) {
return {};
}
return it->second;
}
std::optional<std::string> GetAttributeValue(const std::string &attribute) const
{
auto values = GetAttributeValues(attribute);
if (!values.empty()) {
return values.front();
}
return {};
}
const std::unordered_set<std::string> &GetBoolAttributes() const
{
return set_attributes_;
}
const std::unordered_map<std::string, std::vector<std::string>> &GetAttributes() const
{
return attributes_;
}
virtual std::optional<Error> ValidateData()
{
return {};
}
DEFAULT_COPY_SEMANTIC(Metadata);
DEFAULT_MOVE_SEMANTIC(Metadata);
protected:
virtual std::optional<Error> Validate(const std::string_view &attribute) const = 0;
virtual std::optional<Error> Validate(const std::string_view &attribute,
const std::string_view &value) const = 0;
virtual std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value)
{
std::string key(attribute);
auto it = attributes_.find(key);
if (it == attributes_.cend()) {
std::tie(it, std::ignore) = attributes_.try_emplace(key);
}
it->second.emplace_back(value);
return {};
}
virtual std::optional<Error> Store(const std::string_view &attribute)
{
set_attributes_.emplace(attribute);
return {};
}
virtual void SetFlags(const std::string_view &attribute) = 0;
virtual void SetFlags(const std::string_view &attribute, const std::string_view &value) = 0;
virtual void RemoveFlags(const std::string_view &attribute) = 0;
virtual void RemoveFlags(const std::string_view &attribute, const std::string_view &value) = 0;
bool HasAttribute(const std::string_view &attribute) const
{
std::string key(attribute);
return GetAttribute(key) || GetAttributeValue(key);
}
std::optional<Error> ValidateSize(const std::string_view &value) const;
private:
std::unordered_set<std::string> set_attributes_;
std::unordered_map<std::string, std::vector<std::string>> attributes_;
};
class AnnotationMetadata : public Metadata {
public:
const std::vector<AnnotationData> &GetAnnotations() const
{
return annotations_;
}
void SetAnnotations(std::vector<AnnotationData> &&annotations)
{
annotations_ = std::forward<std::vector<AnnotationData>>(annotations);
}
void AddAnnotations(const std::vector<AnnotationData> &annotations)
{
annotations_.insert(annotations_.end(), annotations.begin(), annotations.end());
}
void DeleteAnnotationElementByName(std::string_view annotation_name, std::string_view annotation_elem_name)
{
auto annotation_iter = std::find_if(annotations_.begin(), annotations_.end(),
[&](pandasm::AnnotationData &annotation) -> bool {
return annotation.GetName() == annotation_name;
});
if (annotation_iter != annotations_.end()) {
annotation_iter->DeleteAnnotationElementByName(annotation_elem_name);
}
}
void DeleteAnnotationByName(const std::string_view &annotation_name)
{
auto annotation_iter = std::find_if(annotations_.begin(), annotations_.end(),
[&](pandasm::AnnotationData &annotation) -> bool {
return annotation.GetName() == annotation_name;
});
if (annotation_iter != annotations_.end()) {
(void)annotations_.erase(annotation_iter);
}
}
void AddAnnotationElementByName(const std::string_view &annotation_name, AnnotationElement &&element)
{
auto annotation_iter = std::find_if(annotations_.begin(), annotations_.end(),
[&](pandasm::AnnotationData &annotation) -> bool {
return annotation.GetName() == annotation_name;
});
if (annotation_iter != annotations_.end()) {
annotation_iter->AddElement(std::move(element));
}
}
void SetOrAddAnnotationElementByIndex(size_t anno_idx, size_t ele_idx, AnnotationElement &&element)
{
ASSERT(anno_idx < annotations_.size());
annotations_[anno_idx].SetOrAddElementByIndex(ele_idx, std::forward<AnnotationElement>(element));
}
std::optional<Error> ValidateData() override;
protected:
std::optional<Error> Store(const std::string_view &attribute) override;
std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value) override;
virtual bool IsAnnotationRecordAttribute([[maybe_unused]] const std::string_view &attribute) const
{
return false;
}
virtual bool IsAnnotationIdAttribute([[maybe_unused]] const std::string_view &attribute) const
{
return false;
}
virtual bool IsAnnotationElementTypeAttribute([[maybe_unused]] const std::string_view &attribute) const
{
return false;
}
virtual bool IsAnnotationElementArrayComponentTypeAttribute(
[[maybe_unused]] const std::string_view &attribute) const
{
return false;
}
virtual bool IsAnnotationElementNameAttribute([[maybe_unused]] const std::string_view &attribute) const
{
return false;
}
virtual bool IsAnnotationElementValueAttribute([[maybe_unused]] const std::string_view &attribute) const
{
return false;
}
private:
class AnnotationElementBuilder {
public:
void Initialize(const std::string_view &name)
{
name_ = name;
is_initialized_ = true;
}
void Reset()
{
name_.clear();
values_.clear();
type_ = {};
component_type_ = {};
is_initialized_ = false;
}
void SetType(Value::Type type)
{
type_ = type;
}
void SetComponentType(Value::Type type)
{
ASSERT(type != Value::Type::ARRAY);
component_type_ = type;
}
std::optional<Error> AddValue(
const std::string_view &value,
const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotation_id_map);
AnnotationElement CreateAnnotationElement()
{
if (IsArray()) {
return AnnotationElement(name_,
std::make_unique<ArrayValue>(component_type_.value(), std::move(values_)));
}
return AnnotationElement(name_, std::make_unique<ScalarValue>(values_.front()));
}
bool IsArray() const
{
return type_.value() == Value::Type::ARRAY;
}
bool IsTypeSet() const
{
return type_.has_value();
}
bool IsComponentTypeSet() const
{
return component_type_.has_value();
}
bool IsInitialized() const
{
return is_initialized_;
}
bool IsCompleted() const
{
if (!IsTypeSet()) {
return false;
}
if (IsArray() && !IsComponentTypeSet()) {
return false;
}
if (!IsArray() && values_.empty()) {
return false;
}
return true;
}
private:
bool is_initialized_ {false};
std::string name_;
std::optional<Value::Type> type_;
std::optional<Value::Type> component_type_;
std::vector<ScalarValue> values_;
};
class AnnotationBuilder {
public:
void Initialize(const std::string_view &name)
{
name_ = name;
is_initialized_ = true;
}
void Reset()
{
name_.clear();
elements_.clear();
id_ = {};
is_initialized_ = false;
}
void SetId(const std::string_view &id)
{
id_ = id;
}
std::string GetId() const
{
ASSERT(HasId());
return id_.value();
}
void AddElement(AnnotationElement &&element)
{
elements_.push_back(std::forward<AnnotationElement>(element));
}
std::unique_ptr<AnnotationData> CreateAnnotationData()
{
return std::make_unique<AnnotationData>(name_, std::move(elements_));
};
void AddAnnnotationDataToVector(std::vector<AnnotationData> *annotations)
{
annotations->emplace_back(name_, std::move(elements_));
}
bool HasId() const
{
return id_.has_value();
}
bool IsInitialized() const
{
return is_initialized_;
}
private:
std::string name_;
std::optional<std::string> id_;
std::vector<AnnotationElement> elements_;
bool is_initialized_ {false};
};
std::optional<Metadata::Error> MeetExpRecordAttribute(const std::string_view &attribute,
const std::string_view &value);
std::optional<Metadata::Error> MeetExpIdAttribute(const std::string_view &attribute, const std::string_view &value);
std::optional<Metadata::Error> MeetExpElementNameAttribute(const std::string_view &attribute,
const std::string_view &value);
std::optional<Metadata::Error> MeetExpElementTypeAttribute(const std::string_view &attribute,
const std::string_view &value);
std::optional<Metadata::Error> MeetExpElementArrayComponentTypeAttribute(const std::string_view &attribute,
const std::string_view &value);
std::optional<Metadata::Error> MeetExpElementValueAttribute(const std::string_view &attribute,
const std::string_view &value);
void InitializeAnnotationBuilder(const std::string_view &name)
{
if (IsParseAnnotation()) {
ResetAnnotationBuilder();
}
annotation_builder_.Initialize(name);
}
void ResetAnnotationBuilder()
{
ASSERT(IsParseAnnotation());
if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
ResetAnnotationElementBuilder();
}
if (annotation_builder_.HasId()) {
id_map_.insert({annotation_builder_.GetId(), annotation_builder_.CreateAnnotationData()});
} else {
annotation_builder_.AddAnnnotationDataToVector(&annotations_);
}
annotation_builder_.Reset();
}
bool IsParseAnnotation() const
{
return annotation_builder_.IsInitialized();
}
void InitializeAnnotationElementBuilder(const std::string_view &name)
{
if (IsParseAnnotationElement() && annotation_element_builder_.IsCompleted()) {
ResetAnnotationElementBuilder();
}
annotation_element_builder_.Initialize(name);
}
void ResetAnnotationElementBuilder()
{
ASSERT(IsParseAnnotationElement());
ASSERT(annotation_element_builder_.IsCompleted());
annotation_builder_.AddElement(annotation_element_builder_.CreateAnnotationElement());
annotation_element_builder_.Reset();
}
bool IsParseAnnotationElement() const
{
return annotation_element_builder_.IsInitialized();
}
AnnotationBuilder annotation_builder_;
AnnotationElementBuilder annotation_element_builder_;
std::vector<AnnotationData> annotations_;
std::unordered_map<std::string, std::unique_ptr<AnnotationData>> id_map_;
};
class ItemMetadata : public AnnotationMetadata {
public:
uint32_t GetAccessFlags() const
{
return access_flags_;
}
void SetAccessFlags(uint32_t access_flags)
{
access_flags_ = access_flags;
}
void AddAccessFlags(uint32_t access_flags)
{
access_flags_ = access_flags_ | access_flags;
}
bool IsForeign() const;
private:
uint32_t access_flags_ {0};
};
class RecordMetadata : public ItemMetadata {
public:
virtual std::string GetBase() const;
virtual std::vector<std::string> GetInterfaces() const;
virtual bool IsAnnotation() const;
virtual bool IsRuntimeAnnotation() const;
virtual bool IsTypeAnnotation() const;
virtual bool IsRuntimeTypeAnnotation() const;
protected:
std::optional<Error> Validate(const std::string_view &attribute) const override;
std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
void SetFlags(const std::string_view &attribute) override;
void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
void RemoveFlags(const std::string_view &attribute) override;
void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
};
class FieldMetadata : public ItemMetadata {
public:
void SetFieldType(const Type &type)
{
field_type_ = type;
}
Type GetFieldType() const
{
return field_type_;
}
void SetValue(const ScalarValue &value)
{
value_ = value;
}
std::optional<ScalarValue> GetValue() const
{
return value_;
}
protected:
std::optional<Error> StoreValue(const std::string_view &attribute, const std::string_view &value) override;
std::optional<Error> Validate(const std::string_view &attribute) const override;
std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
void SetFlags(const std::string_view &attribute) override;
void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
void RemoveFlags(const std::string_view &attribute) override;
void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
virtual bool IsValueAttribute(const std::string_view &attribute)
{
return attribute == "value";
}
private:
Type field_type_;
std::optional<ScalarValue> value_;
};
class FunctionMetadata : public ItemMetadata {
public:
virtual bool IsCtor() const;
virtual bool IsCctor() const;
protected:
std::optional<Error> Validate(const std::string_view &attribute) const override;
std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
void SetFlags(const std::string_view &attribute) override;
void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
void RemoveFlags(const std::string_view &attribute) override;
void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
};
class ParamMetadata : public AnnotationMetadata {
protected:
std::optional<Error> Validate(const std::string_view &attribute) const override;
std::optional<Error> Validate(const std::string_view &attribute, const std::string_view &value) const override;
void SetFlags(const std::string_view &attribute) override;
void SetFlags(const std::string_view &attribute, const std::string_view &value) override;
void RemoveFlags(const std::string_view &attribute) override;
void RemoveFlags(const std::string_view &attribute, const std::string_view &value) override;
};
} // namespace panda::pandasm
#endif // ASSEMBLER_META_H