1 /*
2  * Copyright (c) 2024 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 #include "metadata/metadata_reader.h"
17 
18 #include "metadata/metadata_serializer.h"
19 #include "util/file.h"
20 #include "util/logger.h"
21 
22 namespace OHOS {
23 namespace Idl {
24 std::string MetadataReader::tag_ = "MetadataReader";
25 
ReadMetadataFromFile(const std::string & filePath)26 std::shared_ptr<MetaComponent> MetadataReader::ReadMetadataFromFile(const std::string& filePath)
27 {
28     File file(filePath, File::READ);
29     if (!file.IsValid()) {
30         Logger::E(tag_.c_str(), "Open \"%s\" file failed.", filePath.c_str());
31         return nullptr;
32     }
33 
34     if (!file.Reset()) {
35         Logger::E(tag_.c_str(), "Reset \"%s\" file failed.", filePath.c_str());
36         return nullptr;
37     }
38 
39     MetaComponent header;
40 
41     if (!file.ReadData((void*)&header, sizeof(MetaComponent))) {
42         Logger::E(tag_.c_str(), "Read \"%s\" file failed.", filePath.c_str());
43         return nullptr;
44     }
45 
46     if (header.magic_ != METADATA_MAGIC_NUMBER || header.size_ < 0) {
47         Logger::E(tag_.c_str(), "The metadata in \"%s\" file is bad.", filePath.c_str());
48         return nullptr;
49     }
50 
51     if (!file.Reset()) {
52         Logger::E(tag_.c_str(), "Reset \"%s\" file failed.", filePath.c_str());
53         return nullptr;
54     }
55 
56     void* data = malloc(header.size_);
57     if (data == nullptr) {
58         Logger::E(tag_.c_str(), "Malloc metadata failed.");
59         return nullptr;
60     }
61 
62     if (!file.ReadData(data, header.size_)) {
63         Logger::E(tag_.c_str(), "Read \"%s\" file failed.", filePath.c_str());
64         free(data);
65         return nullptr;
66     }
67 
68     std::shared_ptr<MetaComponent> metadata(reinterpret_cast<MetaComponent *>(data), [](MetaComponent* p) { free(p); });
69 
70     MetadataSerializer serializer((uintptr_t)data);
71     serializer.Deserialize();
72 
73     return metadata;
74 }
75 
ReadMetadataToAst()76 std::unordered_map<std::string, AutoPtr<AST>> MetadataReader::ReadMetadataToAst()
77 {
78     std::unordered_map<std::string, AutoPtr<AST>> allAsts;
79 
80     ast_ = new AST();
81     for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
82         ReadMetaSequenceable(metaComponent_->sequenceables_[i]);
83     }
84 
85     for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
86         ReadMetaInterface(metaComponent_->interfaces_[i]);
87     }
88 
89     ast_->SetFullName(std::string(reinterpret_cast<char*>(metaComponent_->name_)));
90     ast_->SetAStFileType(ASTFileType::AST_IFACE);
91     allAsts[std::string(reinterpret_cast<char*>(metaComponent_->name_))] = ast_;
92 
93     return allAsts;
94 }
95 
ReadMetaSequenceable(MetaSequenceable * mp)96 void MetadataReader::ReadMetaSequenceable(MetaSequenceable* mp)
97 {
98     AutoPtr<ASTSequenceableType> seqType = new ASTSequenceableType();
99 
100     seqType->SetName(std::string(reinterpret_cast<char*>(mp->name_)));
101     seqType->SetNamespace(ast_->ParseNamespace(std::string(reinterpret_cast<char*>(mp->namespace_))));
102     AutoPtr<AST> seqAst = new AST();
103     seqAst->SetFullName(seqType->GetFullName());
104     seqAst->AddSequenceableDef(seqType);
105     seqAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE);
106     ast_->AddImport(seqAst);
107     ast_->AddSequenceableDef(seqType);
108 }
109 
ReadMetaInterface(MetaInterface * mi)110 void MetadataReader::ReadMetaInterface(MetaInterface* mi)
111 {
112     AutoPtr<ASTInterfaceType> interface = new ASTInterfaceType();
113     AutoPtr<ASTAttr> infAttr = new ASTAttr();
114     if (mi->properties_ == INTERFACE_PROPERTY_ONEWAY) {
115         infAttr->SetValue(ASTAttr::ONEWAY);
116     }
117     interface->SetAttribute(infAttr);
118     if (!mi->external_) {
119         interface->SetLicense(std::string(reinterpret_cast<char*>(mi->license_)));
120         ast_->SetLicense(std::string(reinterpret_cast<char*>(mi->license_)));
121     }
122     interface->SetName(std::string(reinterpret_cast<char*>(mi->name_)));
123 
124     interface->SetNamespace(ast_->ParseNamespace(std::string(reinterpret_cast<char*>(mi->namespace_))));
125     interface->SetExternal(mi->external_);
126     ast_->AddInterfaceDef(interface);
127     for (int i = 0; i < mi->methodNumber_; i++) {
128         ReadMetaMethod(interface, mi->methods_[i]);
129     }
130 }
131 
ReadMetaMethod(AutoPtr<ASTInterfaceType> & interface,MetaMethod * mm)132 void MetadataReader::ReadMetaMethod(AutoPtr<ASTInterfaceType>& interface, MetaMethod* mm)
133 {
134     AutoPtr<ASTMethod> method = new ASTMethod();
135     AutoPtr<ASTAttr> methodAttr = new ASTAttr();
136     if (mm->properties_ == METHOD_PROPERTY_ONEWAY) {
137         methodAttr->SetValue(ASTAttr::ONEWAY);
138     }
139     method->SetAttribute(methodAttr);
140 
141     MetaType* type = metaComponent_->types_[mm->returnTypeIndex_];
142     method->SetReturnType(ReadMetaType(type));
143     method->SetName(std::string(reinterpret_cast<char*>((mm->name_))));
144     for (int i = 0; i < mm->parameterNumber_; i++) {
145         ReadMetaParam(method, mm->parameters_[i]);
146     }
147     interface->AddMethod(method);
148 }
149 
ReadMetaParam(AutoPtr<ASTMethod> & method,MetaParameter * mp)150 void MetadataReader::ReadMetaParam(AutoPtr<ASTMethod>& method, MetaParameter* mp)
151 {
152     AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ASTParamAttr::PARAM_NONE);
153 
154     if ((mp->attributes_ & ATTR_IN) == ATTR_IN) {
155         attr->value_ |= ASTParamAttr::PARAM_IN;
156     }
157 
158     if ((mp->attributes_ & ATTR_OUT) == ATTR_OUT) {
159         attr->value_ |= ASTParamAttr::PARAM_OUT;
160     }
161 
162     MetaType* type = metaComponent_->types_[mp->typeIndex_];
163     AutoPtr<ASTParameter> param = new ASTParameter(std::string(reinterpret_cast<char*>((mp->name_))),
164         attr, ReadMetaType(type));
165     method->AddParameter(param);
166 }
167 
ReadMetaType(MetaType * type)168 AutoPtr<ASTType> MetadataReader::ReadMetaType(MetaType* type)
169 {
170     std::string typeName = MetaTypeName(type);
171     AutoPtr<ASTType> astType = ast_->FindType(typeName);
172     switch (type->kind_) {
173         case MetaTypeKind::List:
174             if (astType == nullptr) {
175                 MetaType* elementMt = metaComponent_->types_[type->nestedTypeIndexes_[0]];
176                 AutoPtr<ASTListType> listType = new ASTListType();
177                 listType->SetElementType(ReadMetaType(elementMt));
178                 astType = listType.Get();
179             }
180             break;
181         case MetaTypeKind::Map:
182             if (astType == nullptr) {
183                 MetaType* keyMt = metaComponent_->types_[type->nestedTypeIndexes_[0]];
184                 MetaType* valueMt = metaComponent_->types_[type->nestedTypeIndexes_[1]];
185                 AutoPtr<ASTMapType> mapType = new ASTMapType();
186                 mapType->SetKeyType(ReadMetaType(keyMt));
187                 mapType->SetValueType(ReadMetaType(valueMt));
188                 astType = mapType.Get();
189             }
190             break;
191         case MetaTypeKind::Array:
192             if (astType == nullptr) {
193                 MetaType* elementMt = metaComponent_->types_[type->nestedTypeIndexes_[0]];
194                 AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
195                 arrayType->SetElementType(ReadMetaType(elementMt));
196                 astType = arrayType.Get();
197             }
198             break;
199         default:
200             break;
201     }
202     ast_->AddType(astType);
203     return astType;
204 }
205 
MetaTypeName(MetaType * mt)206 std::string MetadataReader::MetaTypeName(MetaType* mt)
207 {
208     switch (mt->kind_) {
209         case MetaTypeKind::Char:
210             return "char";
211         case MetaTypeKind::Boolean:
212             return "boolean";
213         case MetaTypeKind::Byte:
214             return "byte";
215         case MetaTypeKind::Short:
216             return "short";
217         case MetaTypeKind::Integer:
218             return "int";
219         case MetaTypeKind::Long:
220             return "long";
221         case MetaTypeKind::Float:
222             return "float";
223         case MetaTypeKind::Double:
224             return "double";
225         case MetaTypeKind::String:
226             return "String";
227         case MetaTypeKind::Void:
228             return "void";
229         case MetaTypeKind::Sequenceable: {
230             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
231             return reinterpret_cast<char*>(mp->name_);
232         }
233         case MetaTypeKind::Interface: {
234             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
235             return reinterpret_cast<char*>(mi->name_);
236         }
237         case MetaTypeKind::List: {
238             MetaType* elementMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
239             return "List<" + MetaTypeName(elementMt) + ">";
240         }
241         case MetaTypeKind::Map: {
242             MetaType* keyMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
243             MetaType* valueMt = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
244             return "Map<" + MetaTypeName(keyMt) + ", " + MetaTypeName(valueMt) + ">";
245         }
246         case MetaTypeKind::Array: {
247             MetaType* elementMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
248             return MetaTypeName(elementMt) + "[]";
249         }
250         case MetaTypeKind::Unknown:
251         default:
252             printf("Unknown %d\n", mt->index_);
253             return "unknown";
254     }
255 }
256 } // namespace Idl
257 } // namespace OHOS
258