/** * Copyright (c) 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. */ #include "annotationProto.h" namespace panda::proto { void AnnotationData::Serialize(const panda::pandasm::AnnotationData &anno, protoPanda::AnnotationData &protoAnno) { protoAnno.set_recordname(anno.GetName()); for (const auto &element : anno.GetElements()) { auto *protoElement = protoAnno.add_elements(); AnnotationElement::Serialize(element, *protoElement); } } void AnnotationData::Deserialize(const protoPanda::AnnotationData &protoAnno, panda::pandasm::AnnotationData &anno, panda::ArenaAllocator *allocator) { for (const auto &protoElement : protoAnno.elements()) { panda::pandasm::AnnotationElement &element = AnnotationElement::Deserialize(protoElement, allocator); anno.AddElement(std::move(element)); } } void AnnotationElement::Serialize(const panda::pandasm::AnnotationElement &element, protoPanda::AnnotationElement &protoElement) { protoElement.set_name(element.GetName()); if (element.GetValue()->IsArray()) { protoElement.set_valuetype(protoPanda::AnnotationElement_ValueType::AnnotationElement_ValueType_ARRAY); auto *protoArray = protoElement.mutable_array(); ArrayValue::Serialize(*(element.GetValue()->GetAsArray()), *protoArray); } else { protoElement.set_valuetype(protoPanda::AnnotationElement_ValueType::AnnotationElement_ValueType_SCALAR); auto *protoScalar = protoElement.mutable_scalar(); ScalarValue::Serialize(*(element.GetValue()->GetAsScalar()), *protoScalar); } } panda::pandasm::AnnotationElement &AnnotationElement::Deserialize(const protoPanda::AnnotationElement &protoElement, panda::ArenaAllocator *allocator) { if (protoElement.valuetype() == protoPanda::AnnotationElement_ValueType::AnnotationElement_ValueType_ARRAY) { panda::pandasm::ArrayValue &array = ArrayValue::Deserialize(protoElement.array(), allocator); auto *element = allocator->New(protoElement.name(), std::make_unique(array)); return *element; } panda::pandasm::ScalarValue scalar = ScalarValue::Deserialize(protoElement.scalar(), allocator); auto *element = allocator->New(protoElement.name(), std::make_unique(scalar)); return *element; } void ScalarValue::Serialize(const panda::pandasm::ScalarValue &scalar, protoPanda::ScalarValue &protoScalar) { const auto &valueType = scalar.GetType(); protoScalar.mutable_father()->set_type(static_cast(valueType)); auto type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_UINT64; switch (valueType) { case panda::pandasm::Value::Type::U1: case panda::pandasm::Value::Type::U8: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::U16: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::STRING_NULLPTR: case panda::pandasm::Value::Type::U32: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::U64: protoScalar.set_valueu64(scalar.GetValue()); break; case panda::pandasm::Value::Type::I8: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::I16: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::I32: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::I64: protoScalar.set_valueu64(static_cast(scalar.GetValue())); break; case panda::pandasm::Value::Type::F32: type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_FLOAT; protoScalar.set_valuefloat(scalar.GetValue()); break; case panda::pandasm::Value::Type::F64: type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_DOUBLE; protoScalar.set_valuedouble(scalar.GetValue()); break; case panda::pandasm::Value::Type::STRING: case panda::pandasm::Value::Type::METHOD: case panda::pandasm::Value::Type::ENUM: case panda::pandasm::Value::Type::LITERALARRAY: type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_STRING; protoScalar.set_valuestr(scalar.GetValue()); break; case panda::pandasm::Value::Type::RECORD: { type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_PANDASM_TYPE; auto *protoType = protoScalar.mutable_valuetype(); Type::Serialize(scalar.GetValue(), *protoType); break; } case panda::pandasm::Value::Type::ANNOTATION: { type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_ANNOTATION_DATA; auto *protoAnno = protoScalar.mutable_valueanno(); AnnotationData::Serialize(scalar.GetValue(), *protoAnno); break; } default: std::cerr << "unknown panda::pandasm::Value::Type" << std::endl; UNREACHABLE(); } protoScalar.set_type(type); } panda::pandasm::ScalarValue ScalarValue::Deserialize(const protoPanda::ScalarValue &protoScalar, panda::ArenaAllocator *allocator) { protoPanda::ScalarValue_VariantValueType scalarType = protoScalar.type(); std::variant value; switch (scalarType) { case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_UINT64: { value = static_cast(protoScalar.valueu64()); break; } case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_FLOAT: { value = static_cast(protoScalar.valuefloat()); break; } case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_DOUBLE: { value = static_cast(protoScalar.valuedouble()); break; } case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_STRING: { value = static_cast(protoScalar.valuestr()); break; } case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_PANDASM_TYPE: { value = static_cast(Type::Deserialize(protoScalar.valuetype(), allocator)); break; } case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_ANNOTATION_DATA: { auto &protoAnnotationData = protoScalar.valueanno(); auto *value = allocator->New(protoAnnotationData.recordname()); AnnotationData::Deserialize(protoAnnotationData, *value, allocator); break; } default: UNREACHABLE(); } auto scalar = ScalarValue::CreateScalarValue(static_cast( protoScalar.father().type()), value); return scalar; } panda::pandasm::ScalarValue ScalarValue::CreateScalarValue(const panda::pandasm::Value::Type &type, std::variant &value) { switch (type) { case panda::pandasm::Value::Type::U1: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::U8: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::U16: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::STRING_NULLPTR: { return panda::pandasm::ScalarValue::Create( static_cast(std::get(value))); } case panda::pandasm::Value::Type::U32: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::U64: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::I8: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::I16: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::I32: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::I64: { return panda::pandasm::ScalarValue::Create(static_cast( std::get(value))); } case panda::pandasm::Value::Type::F32: { return panda::pandasm::ScalarValue::Create(std::get(value)); } case panda::pandasm::Value::Type::F64: { return panda::pandasm::ScalarValue::Create(std::get(value)); } case panda::pandasm::Value::Type::STRING: { return panda::pandasm::ScalarValue::Create( std::get(value)); } case panda::pandasm::Value::Type::METHOD: { return panda::pandasm::ScalarValue::Create( std::get(value)); } case panda::pandasm::Value::Type::ENUM: { return panda::pandasm::ScalarValue::Create(std::get(value)); } case panda::pandasm::Value::Type::RECORD: { return panda::pandasm::ScalarValue::Create( std::get(value)); } case panda::pandasm::Value::Type::ANNOTATION: { return panda::pandasm::ScalarValue::Create( std::get(value)); } case panda::pandasm::Value::Type::LITERALARRAY: { return panda::pandasm::ScalarValue::Create( std::get(value)); } default: UNREACHABLE(); } } void ArrayValue::Serialize(const panda::pandasm::ArrayValue &array, protoPanda::ArrayValue &protoArray) { protoArray.mutable_father()->set_type(static_cast(array.GetType())); protoArray.set_componenttype(static_cast(array.GetComponentType())); for (const auto &val : array.GetValues()) { auto *protoScalar = protoArray.add_values(); ScalarValue::Serialize(val, *protoScalar); } } panda::pandasm::ArrayValue &ArrayValue::Deserialize(const protoPanda::ArrayValue &protoArray, panda::ArenaAllocator *allocator) { std::vector values; values.reserve(protoArray.values_size()); for (const auto &protoValue : protoArray.values()) { panda::pandasm::ScalarValue scalar = ScalarValue::Deserialize(protoValue, allocator); values.emplace_back(std::move(scalar)); } auto *array = allocator->New( static_cast(protoArray.componenttype()), values); return *array; } } // panda::proto