* 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<panda::pandasm::AnnotationElement>(protoElement.name(),
std::make_unique<panda::pandasm::ArrayValue>(array));
CHECK_NOT_NULL(element);
return *element;
}
panda::pandasm::ScalarValue scalar = ScalarValue::Deserialize(protoElement.scalar(), allocator);
auto *element = allocator->New<panda::pandasm::AnnotationElement>(protoElement.name(),
std::make_unique<panda::pandasm::ScalarValue>(scalar));
CHECK_NOT_NULL(element);
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<uint32_t>(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<uint64_t>(scalar.GetValue<uint8_t>()));
break;
case panda::pandasm::Value::Type::U16:
protoScalar.set_valueu64(static_cast<uint64_t>(scalar.GetValue<uint16_t>()));
break;
case panda::pandasm::Value::Type::STRING_NULLPTR:
case panda::pandasm::Value::Type::U32:
protoScalar.set_valueu64(static_cast<uint64_t>(scalar.GetValue<uint32_t>()));
break;
case panda::pandasm::Value::Type::U64:
protoScalar.set_valueu64(scalar.GetValue<uint64_t>());
break;
case panda::pandasm::Value::Type::I8:
protoScalar.set_valueu64(static_cast<uint64_t>(scalar.GetValue<int8_t>()));
break;
case panda::pandasm::Value::Type::I16:
protoScalar.set_valueu64(static_cast<uint64_t>(scalar.GetValue<int16_t>()));
break;
case panda::pandasm::Value::Type::I32:
protoScalar.set_valueu64(static_cast<uint64_t>(scalar.GetValue<int32_t>()));
break;
case panda::pandasm::Value::Type::I64:
protoScalar.set_valueu64(static_cast<uint64_t>(scalar.GetValue<int64_t>()));
break;
case panda::pandasm::Value::Type::F32:
type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_FLOAT;
protoScalar.set_valuefloat(scalar.GetValue<float>());
break;
case panda::pandasm::Value::Type::F64:
type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_DOUBLE;
protoScalar.set_valuedouble(scalar.GetValue<double>());
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<std::string>());
break;
case panda::pandasm::Value::Type::RECORD: {
type = protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_PANDASM_TYPE;
auto *protoType = protoScalar.mutable_valuetype();
Type::Serialize(scalar.GetValue<panda::pandasm::Type>(), *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<panda::pandasm::AnnotationData>(), *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<uint64_t, float, double, std::string, panda::pandasm::Type, panda::pandasm::AnnotationData> value;
switch (scalarType) {
case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_UINT64: {
value = static_cast<uint64_t>(protoScalar.valueu64());
break;
}
case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_FLOAT: {
value = static_cast<float>(protoScalar.valuefloat());
break;
}
case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_DOUBLE: {
value = static_cast<double>(protoScalar.valuedouble());
break;
}
case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_STRING: {
value = static_cast<std::string>(protoScalar.valuestr());
break;
}
case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_PANDASM_TYPE: {
value = static_cast<panda::pandasm::Type>(Type::Deserialize(protoScalar.valuetype(), allocator));
break;
}
case protoPanda::ScalarValue_VariantValueType::ScalarValue_VariantValueType_ANNOTATION_DATA: {
auto &protoAnnotationData = protoScalar.valueanno();
auto *value = allocator->New<panda::pandasm::AnnotationData>(protoAnnotationData.recordname());
CHECK_NOT_NULL(value);
AnnotationData::Deserialize(protoAnnotationData, *value, allocator);
break;
}
default:
UNREACHABLE();
}
auto scalar = ScalarValue::CreateScalarValue(static_cast<panda::pandasm::Value::Type>(
protoScalar.father().type()), value);
return scalar;
}
panda::pandasm::ScalarValue ScalarValue::CreateScalarValue(const panda::pandasm::Value::Type &type,
std::variant<uint64_t, float, double, std::string, panda::pandasm::Type, panda::pandasm::AnnotationData> &value)
{
switch (type) {
case panda::pandasm::Value::Type::U1: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::U1>(static_cast<uint8_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::U8: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::U8>(static_cast<uint8_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::U16: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::U16>(static_cast<uint16_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::STRING_NULLPTR: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::STRING_NULLPTR>(
static_cast<uint32_t>(std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::U32: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::U32>(static_cast<uint32_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::U64: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::U64>(static_cast<uint64_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::I8: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::I8>(static_cast<int8_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::I16: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::I16>(static_cast<int16_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::I32: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::I32>(static_cast<int32_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::I64: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::I64>(static_cast<int64_t>(
std::get<uint64_t>(value)));
}
case panda::pandasm::Value::Type::F32: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::F32>(std::get<float>(value));
}
case panda::pandasm::Value::Type::F64: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::F64>(std::get<double>(value));
}
case panda::pandasm::Value::Type::STRING: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::STRING>(
std::get<std::string>(value));
}
case panda::pandasm::Value::Type::METHOD: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::METHOD>(
std::get<std::string>(value));
}
case panda::pandasm::Value::Type::ENUM: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::ENUM>(std::get<std::string>(value));
}
case panda::pandasm::Value::Type::RECORD: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::RECORD>(
std::get<panda::pandasm::Type>(value));
}
case panda::pandasm::Value::Type::ANNOTATION: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::ANNOTATION>(
std::get<panda::pandasm::AnnotationData>(value));
}
case panda::pandasm::Value::Type::LITERALARRAY: {
return panda::pandasm::ScalarValue::Create<panda::pandasm::Value::Type::LITERALARRAY>(
std::get<std::string>(value));
}
default:
UNREACHABLE();
}
}
void ArrayValue::Serialize(const panda::pandasm::ArrayValue &array, protoPanda::ArrayValue &protoArray)
{
protoArray.mutable_father()->set_type(static_cast<uint32_t>(array.GetType()));
protoArray.set_componenttype(static_cast<uint32_t>(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<panda::pandasm::ScalarValue> 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<panda::pandasm::ArrayValue>(
static_cast<panda::pandasm::Value::Type>(protoArray.componenttype()), values);
CHECK_NOT_NULL(array);
return *array;
}
}