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_dumper.h"
17 #include "util/string_builder.h"
18 
19 namespace OHOS {
20 namespace Idl {
21 std::string MetadataDumper::tab_ = "    ";
Dump(const std::string & prefix)22 std::string MetadataDumper::Dump(const std::string& prefix)
23 {
24     if (metaComponent_ == nullptr) {
25         return "";
26     }
27 
28     return DumpMetaComponent(metaComponent_, prefix);
29 }
30 
DumpMetaComponent(MetaComponent * mc,const std::string & prefix)31 std::string MetadataDumper::DumpMetaComponent(MetaComponent* mc, const std::string& prefix)
32 {
33     StringBuilder sb;
34 
35     sb.Append(prefix).Append("MetaComponent\n");
36     sb.Append(prefix).Append("{\n");
37     sb.Append(prefix + tab_).AppendFormat("\"magic_\" : \"0x%x\",\n", mc->magic_);
38     sb.Append(prefix + tab_).AppendFormat("\"size_\" : \"%d\",\n", mc->size_);
39     sb.Append(prefix + tab_).AppendFormat("\"name_\" : \"%s\",\n", mc->name_);
40     sb.Append(prefix + tab_).AppendFormat("\"namespaceNumber_\" : \"%d\",\n", mc->namespaceNumber_);
41     sb.Append(prefix + tab_).AppendFormat("\"sequenceableNumber_\" : \"%d\",\n", mc->sequenceableNumber_);
42     sb.Append(prefix + tab_).AppendFormat("\"interfaceNumber_\" : \"%d\",\n", mc->interfaceNumber_);
43     sb.Append(prefix + tab_).AppendFormat("\"typeNumber_\" : \"%d\",\n", mc->typeNumber_);
44 
45     DumpMetaNamespaces(sb, mc, prefix);
46     DumpMetaSequenceables(sb, mc, prefix);
47     DumpMetaInterfaces(sb, mc, prefix);
48 
49     sb.Append(prefix + tab_).AppendFormat("\"stringPoolSize_\" : \"%d\"\n", mc->stringPoolSize_);
50 
51     sb.Append(prefix).Append("}\n");
52 
53     return sb.ToString();
54 }
55 
DumpMetaNamespaces(StringBuilder & sb,MetaComponent * mc,const std::string & prefix)56 void MetadataDumper::DumpMetaNamespaces(StringBuilder& sb, MetaComponent* mc, const std::string& prefix)
57 {
58     if (mc->namespaceNumber_ == 0) {
59         sb.Append(prefix + tab_).Append("\"namespaces_\" : [],\n");
60     } else {
61         sb.Append(prefix + tab_).Append("\"namespaces_\" : [\n");
62         for (int i = 0; i < mc->namespaceNumber_; i++) {
63             DumpMetaNamespace(sb, mc->namespaces_[i], prefix + tab_ + tab_);
64             if (i != mc->namespaceNumber_ - 1) {
65                 sb.Append(",\n");
66             }
67         }
68         sb.Append("\n" + prefix + tab_).Append("],\n");
69     }
70 }
71 
DumpMetaNamespace(StringBuilder & sb,MetaNamespace * mn,const std::string & prefix)72 void MetadataDumper::DumpMetaNamespace(StringBuilder& sb, MetaNamespace* mn, const std::string& prefix)
73 {
74     sb.Append(prefix).Append("{\n");
75     sb.Append(prefix + tab_).AppendFormat("\"name_\" : \"%s\",\n", mn->name_);
76     sb.Append(prefix + tab_).AppendFormat("\"sequenceableNumber_\" : \"%d\",\n", mn->sequenceableNumber_);
77     sb.Append(prefix + tab_).AppendFormat("\"interfaceNumber_\" : \"%d\",\n", mn->interfaceNumber_);
78     sb.Append(prefix + tab_).AppendFormat("\"namespaceNumber_\" : \"%d\",\n", mn->namespaceNumber_);
79 
80     if (mn->sequenceableNumber_ == 0) {
81         sb.Append(prefix + tab_).Append("\"sequenceableIndexes_\" : [],\n");
82     } else {
83         sb.Append(prefix + tab_).Append("\"sequenceableIndexes_\" : [\n");
84         for (int i = 0; i < mn->sequenceableNumber_; i++) {
85             MetaSequenceable* mp = metaComponent_->sequenceables_[i];
86             sb.Append(prefix + tab_ + tab_).AppendFormat("{ \"name\" : \"%s\" }", mp->name_);
87             if (i != mn->sequenceableNumber_ - 1) {
88                 sb.Append(",\n");
89             }
90         }
91         sb.Append("\n" + prefix + tab_).Append("],\n");
92     }
93 
94     if (mn->interfaceNumber_ == 0) {
95         sb.Append(prefix + tab_).Append("\"interfaceIndexes_\" : [],\n");
96     } else {
97         sb.Append(prefix + tab_).Append("\"interfaceIndexes_\" : [\n");
98         for (int i = 0; i < mn->interfaceNumber_; i++) {
99             MetaInterface* mi = metaComponent_->interfaces_[mn->interfaceIndexes_[i]];
100             sb.Append(prefix + tab_ + tab_).AppendFormat("{ \"name\" : \"%s\" }", mi->name_);
101             if (i != mn->interfaceNumber_ - 1) {
102                 sb.Append(",\n");
103             }
104         }
105         sb.Append("\n" + prefix + tab_).Append("],\n");
106     }
107 
108     if (mn->namespaceNumber_ == 0) {
109         sb.Append(prefix + tab_).Append("\"namespaces_\" : []\n");
110     } else {
111         sb.Append(prefix + tab_).Append("\"namespaces_\" : [\n");
112         for (int i = 0; i < mn->namespaceNumber_; i++) {
113             MetaNamespace* innermn = mn->namespaces_[i];
114             DumpMetaNamespace(sb, innermn, prefix + tab_ + tab_);
115             if (i != mn->namespaceNumber_ - 1) {
116                 sb.Append(",\n");
117             }
118         }
119         sb.Append("\n" + prefix + tab_).Append("]\n");
120     }
121 
122     sb.Append(prefix).Append("}");
123 }
124 
DumpMetaSequenceables(StringBuilder & sb,MetaComponent * mc,const std::string & prefix)125 void MetadataDumper::DumpMetaSequenceables(StringBuilder& sb, MetaComponent* mc, const std::string& prefix)
126 {
127     if (mc->sequenceableNumber_ == 0) {
128         sb.Append(prefix + tab_).Append("\"sequenceables_\" : [],\n");
129     } else {
130         sb.Append(prefix + tab_).Append("\"sequenceables_\" : [\n");
131         for (int i = 0; i < mc->sequenceableNumber_; i++) {
132             DumpMetaSequenceable(sb, mc->sequenceables_[i], prefix + tab_ + tab_);
133             if (i != mc->sequenceableNumber_ - 1) {
134                 sb.Append(",\n");
135             }
136         }
137         sb.Append("\n" + prefix + tab_).Append("],\n");
138     }
139 }
140 
DumpMetaSequenceable(StringBuilder & sb,MetaSequenceable * mp,const std::string & prefix)141 void MetadataDumper::DumpMetaSequenceable(StringBuilder& sb, MetaSequenceable* mp, const std::string& prefix)
142 {
143     sb.Append(prefix).Append("{\n");
144     sb.Append(prefix + tab_).AppendFormat("\"name_\" : \"%s\",\n", mp->name_);
145     sb.Append(prefix + tab_).AppendFormat("\"namespace_\" : \"%s\"\n", mp->namespace_);
146     sb.Append(prefix).Append("}");
147 }
148 
DumpMetaInterfaces(StringBuilder & sb,MetaComponent * mc,const std::string & prefix)149 void MetadataDumper::DumpMetaInterfaces(StringBuilder& sb, MetaComponent* mc, const std::string& prefix)
150 {
151     if (mc->interfaceNumber_ == 0) {
152         sb.Append(prefix + tab_).Append("\"interfaces_\" : [],\n");
153     } else {
154         sb.Append(prefix + tab_).Append("\"interfaces_\" : [\n");
155         for (int i = 0; i < mc->interfaceNumber_; i++) {
156             DumpMetaInterface(sb, mc->interfaces_[i], prefix + tab_ + tab_);
157             if (i != mc->interfaceNumber_ - 1) {
158                 sb.Append(",\n");
159             }
160         }
161         sb.Append("\n" + prefix + tab_).Append("],\n");
162     }
163 }
164 
DumpMetaInterface(StringBuilder & sb,MetaInterface * mi,const std::string & prefix)165 void MetadataDumper::DumpMetaInterface(StringBuilder& sb, MetaInterface* mi, const std::string& prefix)
166 {
167     sb.Append(prefix).Append("{\n");
168     sb.Append(prefix + tab_).AppendFormat("\"name_\" : \"%s\",\n", mi->name_);
169     sb.Append(prefix + tab_).AppendFormat("\"namespace_\" : \"%s\",\n", mi->namespace_);
170     sb.Append(prefix + tab_).AppendFormat("\"properties_\" : \"%s\",\n",
171         (mi->properties_ & INTERFACE_PROPERTY_ONEWAY) != 0 ? "oneway" : "");
172     sb.Append(prefix + tab_).AppendFormat("\"methodNumber_\" : \"%d\",\n", mi->methodNumber_);
173     sb.Append(prefix + tab_).AppendFormat("\"external_\" : \"%d\",\n", mi->external_);
174 
175     if (mi->methodNumber_ == 0) {
176         sb.Append(prefix + tab_).Append("\"methods_\" : []\n");
177     } else {
178         sb.Append(prefix + tab_).Append("\"methods_\" : [\n");
179         for (int i = 0; i < mi->methodNumber_; i++) {
180             DumpMetaMethod(sb, mi->methods_[i], prefix + tab_ + tab_);
181             if (i != mi->methodNumber_ - 1) {
182                 sb.Append(",\n");
183             }
184         }
185         sb.Append("\n" + prefix + tab_).Append("]\n");
186     }
187 
188     sb.Append(prefix).Append("}");
189 }
190 
DumpMetaMethod(StringBuilder & sb,MetaMethod * mm,const std::string & prefix)191 void MetadataDumper::DumpMetaMethod(StringBuilder& sb, MetaMethod* mm, const std::string& prefix)
192 {
193     sb.Append(prefix).Append("{\n");
194     sb.Append(prefix + tab_).AppendFormat("\"name_\" : \"%s\",\n", mm->name_);
195     sb.Append(prefix + tab_).AppendFormat("\"signature_\" : \"%s\",\n", mm->signature_);
196     sb.Append(prefix + tab_).AppendFormat("\"properties_\" : \"%s\",\n",
197         (mm->properties_ & METHOD_PROPERTY_ONEWAY) != 0 ? "oneway" : "");
198     MetaType* type = metaComponent_->types_[mm->returnTypeIndex_];
199     sb.Append(prefix + tab_).AppendFormat("\"returnType_\" : \"%s\",\n", DumpMetaType(type).c_str());
200     sb.Append(prefix + tab_).AppendFormat("\"parameterNumber_\" : \"%d\",\n", mm->parameterNumber_);
201 
202     if (mm->parameterNumber_ == 0) {
203         sb.Append(prefix + tab_).Append("\"parameters_\" : []\n");
204     } else {
205         sb.Append(prefix + tab_).Append("\"parameters_\" : [\n");
206         for (int i = 0; i < mm->parameterNumber_; i++) {
207             DumpMetaParameter(sb, mm->parameters_[i], prefix + tab_ + tab_);
208             if (i != mm->parameterNumber_ - 1) {
209                 sb.Append(",\n");
210             }
211         }
212         sb.Append("\n" + prefix + tab_).Append("]\n");
213     }
214 
215     sb.Append(prefix).Append("}");
216 }
217 
DumpMetaParameter(StringBuilder & sb,MetaParameter * mp,const std::string & prefix)218 void MetadataDumper::DumpMetaParameter(StringBuilder& sb, MetaParameter* mp, const std::string& prefix)
219 {
220     sb.Append(prefix).Append("{\n");
221     sb.Append(prefix + tab_).AppendFormat("\"name_\" : \"%s\",\n", mp->name_);
222     sb.Append(prefix + tab_).Append("\"attributes_\" : \"");
223     bool addComma = false;
224     if ((mp->attributes_ & ATTR_IN) == ATTR_IN) {
225         sb.Append("in");
226         addComma = true;
227     }
228     if ((mp->attributes_ & ATTR_OUT) == ATTR_OUT) {
229         sb.Append(addComma ? ", out" : "out");
230     }
231     sb.Append("\",\n");
232     MetaType* type = metaComponent_->types_[mp->typeIndex_];
233     sb.Append(prefix + tab_).AppendFormat("\"type_\" : \"%s\"\n", DumpMetaType(type).c_str());
234 
235     sb.Append(prefix).Append("}");
236 }
237 
DumpMetaType(MetaType * mt)238 std::string MetadataDumper::DumpMetaType(MetaType* mt)
239 {
240     switch (mt->kind_) {
241         case MetaTypeKind::Char:
242             return "char";
243         case MetaTypeKind::Boolean:
244             return "boolean";
245         case MetaTypeKind::Byte:
246             return "byte";
247         case MetaTypeKind::Short:
248             return "short";
249         case MetaTypeKind::Integer:
250             return "int";
251         case MetaTypeKind::Long:
252             return "long";
253         case MetaTypeKind::Float:
254             return "float";
255         case MetaTypeKind::Double:
256             return "double";
257         case MetaTypeKind::String:
258             return "String";
259         case MetaTypeKind::Void:
260             return "void";
261         case MetaTypeKind::Sequenceable: {
262             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
263             return reinterpret_cast<char*>(mp->name_);
264         }
265         case MetaTypeKind::Interface: {
266             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
267             return reinterpret_cast<char*>(mi->name_);
268         }
269         case MetaTypeKind::List: {
270             MetaType* elementMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
271             return "List<" + DumpMetaType(elementMt) + ">";
272         }
273         case MetaTypeKind::Map: {
274             MetaType* keyMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
275             MetaType* valueMt = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
276             return "Map<" + DumpMetaType(keyMt) + ", " + DumpMetaType(valueMt) + ">";
277         }
278         case MetaTypeKind::Array: {
279             MetaType* elementMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
280             return DumpMetaType(elementMt) + "[]";
281         }
282         case MetaTypeKind::Unknown:
283         default:
284             printf("Unknown %d\n", mt->index_);
285             return "unknown";
286     }
287 }
288 } // namespace Idl
289 } // namespace OHOS
290