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 "hdi_code_emitter.h"
17 #include "type/hdi_boolean_type_emitter.h"
18 #include "type/hdi_byte_type_emitter.h"
19 #include "type/hdi_short_type_emitter.h"
20 #include "type/hdi_int_type_emitter.h"
21 #include "type/hdi_long_type_emitter.h"
22 #include "type/hdi_float_type_emitter.h"
23 #include "type/hdi_double_type_emitter.h"
24 #include "type/hdi_uchar_type_emitter.h"
25 #include "type/hdi_ushort_type_emitter.h"
26 #include "type/hdi_uint_type_emitter.h"
27 #include "type/hdi_ulong_type_emitter.h"
28 #include "type/hdi_string_type_emitter.h"
29 #include "type/hdi_fd_type_emitter.h"
30 #include "type/hdi_seq_type_emitter.h"
31 #include "type/hdi_interface_type_emitter.h"
32 #include "type/hdi_map_type_emitter.h"
33 #include "type/hdi_array_type_emitter.h"
34 #include "type/hdi_enum_type_emitter.h"
35 #include "type/hdi_struct_type_emitter.h"
36 #include "type/hdi_union_type_emitter.h"
37 #include "type/hdi_smq_type_emitter.h"
38 #include "type/hdi_native_buffer_type_emitter.h"
39 #include "type/hdi_pointer_type_emitter.h"
40 
41 #include <cctype>
42 #include "util/file.h"
43 #include "util/options.h"
44 
45 namespace OHOS {
46 namespace Idl {
47 HDICodeEmitter::TypeEmitterMap HDICodeEmitter::basicEmitters_ = {
48     {TypeKind::TYPE_BOOLEAN,           new HdiBooleanTypeEmitter()         },
49     {TypeKind::TYPE_BYTE,              new HdiByteTypeEmitter()            },
50     {TypeKind::TYPE_SHORT,             new HdiShortTypeEmitter()           },
51     {TypeKind::TYPE_INT,               new HdiIntTypeEmitter()             },
52     {TypeKind::TYPE_LONG,              new HdiLongTypeEmitter()            },
53     {TypeKind::TYPE_FLOAT,             new HdiFloatTypeEmitter()           },
54     {TypeKind::TYPE_DOUBLE,            new HdiDoubleTypeEmitter()          },
55     {TypeKind::TYPE_UCHAR,             new HdiUcharTypeEmitter()           },
56     {TypeKind::TYPE_USHORT,            new HdiUshortTypeEmitter()          },
57     {TypeKind::TYPE_UINT,              new HdiUintTypeEmitter()            },
58     {TypeKind::TYPE_ULONG,             new HdiUlongTypeEmitter()           },
59     {TypeKind::TYPE_STRING,            new HdiStringTypeEmitter()          },
60     {TypeKind::TYPE_FILEDESCRIPTOR,    new HdiFdTypeEmitter()              },
61     {TypeKind::TYPE_ASHMEM,            new HdiAshmemTypeEmitter()          },
62     {TypeKind::TYPE_NATIVE_BUFFER,     new HdiNativeBufferTypeEmitter()    },
63     {TypeKind::TYPE_POINTER,           new HdiPointerTypeEmitter()         },
64 };
65 
OutPut(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)66 bool HDICodeEmitter::OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
67 {
68     if (!Reset(ast, targetDirectory, mode)) {
69         return false;
70     }
71 
72     EmitCode();
73     return true;
74 }
75 
Reset(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)76 bool HDICodeEmitter::Reset(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
77 {
78     if (ast == nullptr || targetDirectory.empty()) {
79         return false;
80     }
81 
82     CleanData();
83 
84     mode_ = mode;
85     ast_ = ast;
86     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
87         interface_ = ast_->GetInterfaceDef();
88         interfaceName_ = interface_->GetName();
89         std::string nameSpace = interface_->GetNamespace()->ToString();
90         interfaceFullName_ = nameSpace + interfaceName_;
91         baseName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_;
92         proxyName_ = baseName_ + "Proxy";
93         proxyFullName_ = nameSpace + proxyName_;
94 
95         stubName_ = baseName_ + "Stub";
96         stubFullName_ = nameSpace + stubName_;
97 
98         implName_ = baseName_ + "Service";
99         implFullName_ = nameSpace + implName_;
100     } else if (ast_->GetASTFileType() == ASTFileType::AST_TYPES) {
101         baseName_ = ast_->GetName();
102     } else if (ast_->GetASTFileType() == ASTFileType::AST_SEQUENCEABLE) {
103         baseName_ = ast_->GetName();
104     }
105 
106     majorVerName_ = StringHelper::Format("%s_MAJOR_VERSION", ConstantName(interfaceName_).c_str());
107     minorVerName_ = StringHelper::Format("%s_MINOR_VERSION", ConstantName(interfaceName_).c_str());
108 
109     std::string prefix = StringHelper::Format("%c%s", tolower(baseName_[0]), baseName_.substr(1).c_str());
110     HdiTypeEmitter::dataParcelName_ = prefix + "Data";
111     HdiTypeEmitter::replyParcelName_ = prefix + "Reply";
112     optionName_ = prefix + "Option";
113     HdiTypeEmitter::errorCodeName_ = prefix + "Ret";
114     flagOfSetMemName_ = prefix + "MemSet";
115 
116     if (!ResolveDirectory(targetDirectory)) {
117         return false;
118     }
119 
120     return true;
121 }
122 
CleanData()123 void HDICodeEmitter::CleanData()
124 {
125     ast_ = nullptr;
126     interface_ = nullptr;
127     directory_ = "";
128     interfaceName_ = "";
129     interfaceFullName_ = "";
130     baseName_ = "";
131     proxyName_ = "";
132     proxyFullName_ = "";
133     stubName_ = "";
134     stubFullName_ = "";
135     implName_ = "";
136     implFullName_ = "";
137     HdiTypeEmitter::dataParcelName_ = "";
138     HdiTypeEmitter::replyParcelName_ = "";
139     optionName_ = "";
140     HdiTypeEmitter::errorCodeName_ = "";
141 }
142 
GetNameWithNamespace(AutoPtr<ASTNamespace> space,std::string name) const143 std::string HDICodeEmitter::GetNameWithNamespace(AutoPtr<ASTNamespace> space, std::string name) const
144 {
145     std::vector<std::string> namespaceVec = StringHelper::Split(space->ToString(), ".");
146     std::regex rVer("[V|v][0-9]+_[0-9]+");
147     std::vector<std::string> result;
148     bool findVersion = false;
149 
150     std::string rootPackage = Options::GetInstance().GetRootPackage(space->ToString());
151     size_t rootPackageNum = StringHelper::Split(rootPackage, ".").size();
152 
153     for (size_t i = 0; i < namespaceVec.size(); i++) {
154         std::string ns;
155         if (i < rootPackageNum) {
156             ns = StringHelper::StrToUpper(namespaceVec[i]);
157         } else if (!findVersion && std::regex_match(namespaceVec[i].c_str(), rVer)) {
158             ns = StringHelper::Replace(namespaceVec[i], 'v', 'V');
159             findVersion = true;
160         } else {
161             if (findVersion) {
162                 ns = namespaceVec[i];
163             } else {
164                 ns = PascalName(namespaceVec[i]);
165             }
166         }
167 
168         result.emplace_back(ns);
169     }
170     StringBuilder sb;
171     for (const auto &ns : result) {
172         sb.AppendFormat("%s::", ns.c_str());
173     }
174     sb.Append(name);
175     return sb.ToString();
176 }
177 
GetTypeEmitter(AutoPtr<ASTType> astType) const178 AutoPtr<HdiTypeEmitter> HDICodeEmitter::GetTypeEmitter(AutoPtr<ASTType> astType) const
179 {
180     AutoPtr<HdiTypeEmitter> typeEmitter;
181     auto basicTypePair = basicEmitters_.find(astType->GetTypeKind());
182     if (basicTypePair != basicEmitters_.end()) {
183         typeEmitter = (static_cast<HdiTypeEmitter*>(basicTypePair->second.Get()));
184     }
185 
186     if (typeEmitter == nullptr) {
187         typeEmitter = NewTypeEmitter(astType);
188     }
189 
190     typeEmitter->SetName(astType->GetName());
191     typeEmitter->SetPod(astType->IsPod());
192     if (astType->IsSequenceableType() || astType->IsInterfaceType() ||
193         astType->IsEnumType() || astType->IsStructType() || astType->IsUnionType()) {
194         typeEmitter->SetTypeName(GetNameWithNamespace(astType->GetNamespace(), astType->GetName()));
195     } else {
196         typeEmitter->SetTypeName(astType->ToString());
197     }
198 
199     return typeEmitter;
200 }
201 
NewTypeEmitter(AutoPtr<ASTType> astType) const202 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewTypeEmitter(AutoPtr<ASTType> astType) const
203 {
204     switch (astType->GetTypeKind()) {
205         case TypeKind::TYPE_MAP:
206             return NewMapTypeEmitter(astType);
207         case TypeKind::TYPE_ARRAY:
208             return NewArrayTypeEmitter(astType);
209         case TypeKind::TYPE_LIST:
210             return NewListTypeEmitter(astType);
211         case TypeKind::TYPE_ENUM:
212             return NewEnumTypeEmitter(astType);
213         case TypeKind::TYPE_STRUCT:
214             return NewStructTypeEmitter(astType);
215         case TypeKind::TYPE_UNION:
216             return NewUnionTypeEmitter(astType);
217         case TypeKind::TYPE_SMQ:
218             return NewSmqTypeEmitter(astType);
219         case TypeKind::TYPE_SEQUENCEABLE:
220             return new HdiSeqTypeEmitter();
221         case TypeKind::TYPE_INTERFACE:
222             return new HdiInterfaceTypeEmitter();
223         default: {
224             // type not match, new a empty emitter
225             AutoPtr<HdiTypeEmitter> typeEmitter = new HdiTypeEmitter();
226             return typeEmitter;
227         }
228     }
229 }
230 
NewMapTypeEmitter(AutoPtr<ASTType> astType) const231 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewMapTypeEmitter(AutoPtr<ASTType> astType) const
232 {
233     AutoPtr<HdiMapTypeEmitter> mapTypeEmitter = new HdiMapTypeEmitter();
234     AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(astType.Get()))->GetKeyType();
235     AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(astType.Get()))->GetValueType();
236     AutoPtr<HdiTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
237     AutoPtr<HdiTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
238     mapTypeEmitter->SetKeyEmitter(keyEmitter);
239     mapTypeEmitter->SetValueEmitter(valueEmitter);
240     return mapTypeEmitter.Get();
241 }
242 
NewArrayTypeEmitter(AutoPtr<ASTType> astType) const243 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewArrayTypeEmitter(AutoPtr<ASTType> astType) const
244 {
245     AutoPtr<HdiArrayTypeEmitter> arrayTypeEmitter = new HdiArrayTypeEmitter();
246     AutoPtr<ASTType> elemType = (static_cast<ASTArrayType*>(astType.Get()))->GetElementType();
247     AutoPtr<HdiTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
248     arrayTypeEmitter->SetElementEmitter(elemEmitter);
249     return arrayTypeEmitter.Get();
250 }
251 
NewListTypeEmitter(AutoPtr<ASTType> astType) const252 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewListTypeEmitter(AutoPtr<ASTType> astType) const
253 {
254     AutoPtr<HdiListTypeEmitter> listTypeEmitter = new HdiListTypeEmitter();
255     AutoPtr<ASTType> elemType = (static_cast<ASTListType*>(astType.Get()))->GetElementType();
256     AutoPtr<HdiTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
257     listTypeEmitter->SetElementEmitter(elemEmitter);
258     return listTypeEmitter.Get();
259 }
260 
NewEnumTypeEmitter(AutoPtr<ASTType> astType) const261 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewEnumTypeEmitter(AutoPtr<ASTType> astType) const
262 {
263     AutoPtr<HdiEnumTypeEmitter> enumTypeEmitter = new HdiEnumTypeEmitter();
264     AutoPtr<ASTEnumType> enumType = (static_cast<ASTEnumType*>(astType.Get()));
265     if (enumType->GetBaseType() != nullptr) {
266         AutoPtr<HdiTypeEmitter> baseTypeEmitter = GetTypeEmitter(enumType->GetBaseType());
267         enumTypeEmitter->SetBaseTypeName(baseTypeEmitter->EmitCppType());
268     }
269     for (auto it : enumType->GetMembers()) {
270         if (it->GetExprValue() == nullptr) {
271             enumTypeEmitter->AddMember(new HdiEnumValueEmitter(it->GetName(), std::string("")));
272         } else {
273             enumTypeEmitter->AddMember(new HdiEnumValueEmitter(it->GetName(), it->GetExprValue()->EmitCode()));
274         }
275     }
276     return enumTypeEmitter.Get();
277 }
278 
NewStructTypeEmitter(AutoPtr<ASTType> astType) const279 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewStructTypeEmitter(AutoPtr<ASTType> astType) const
280 {
281     AutoPtr<HdiStructTypeEmitter> structTypeEmitter = new HdiStructTypeEmitter();
282     AutoPtr<ASTStructType> structType = (static_cast<ASTStructType*>(astType.Get()));
283     for (auto it : structType->GetMembers()) {
284         structTypeEmitter->AddMember(std::get<0>(it), GetTypeEmitter(std::get<1>(it)));
285     }
286     return structTypeEmitter.Get();
287 }
288 
NewUnionTypeEmitter(AutoPtr<ASTType> astType) const289 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewUnionTypeEmitter(AutoPtr<ASTType> astType) const
290 {
291     AutoPtr<HdiUnionTypeEmitter> unionTypeEmitter = new HdiUnionTypeEmitter();
292     AutoPtr<ASTUnionType> unionType = (static_cast<ASTUnionType*>(astType.Get()));
293     for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
294         unionTypeEmitter->AddMember(unionType->GetMemberName(i), GetTypeEmitter(unionType->GetMemberType(i)));
295     }
296     return unionTypeEmitter.Get();
297 }
298 
NewSmqTypeEmitter(AutoPtr<ASTType> astType) const299 AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewSmqTypeEmitter(AutoPtr<ASTType> astType) const
300 {
301     AutoPtr<HdiSmqTypeEmitter> smqTypeEmitter = new HdiSmqTypeEmitter();
302     AutoPtr<ASTType> innerType = (static_cast<ASTSmqType*>(astType.Get()))->GetInnerType();
303     AutoPtr<HdiTypeEmitter> innerTypeEmitter = GetTypeEmitter(innerType);
304     smqTypeEmitter->SetInnerTypeEmitter(innerTypeEmitter);
305     return smqTypeEmitter.Get();
306 }
307 
EmitUtilMethods(StringBuilder & sb,bool isDecl)308 void HDICodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
309 {
310     (void)sb;
311     (void)isDecl;
312 }
313 
EmitUtilMethodMap(StringBuilder & sb,const UtilMethodMap & methods)314 void HDICodeEmitter::EmitUtilMethodMap(StringBuilder &sb, const UtilMethodMap &methods)
315 {
316     // generator util methods
317     for (const auto &methodPair : methods) {
318         sb.Append(methodPair.second);
319     }
320 }
321 
EmitInterfaceBuffSizeMacro(StringBuilder & sb) const322 void HDICodeEmitter::EmitInterfaceBuffSizeMacro(StringBuilder &sb) const
323 {
324     sb.AppendFormat("#ifndef %s\n", MAX_BUFF_SIZE_MACRO);
325     sb.AppendFormat("#define %s (%s)\n", MAX_BUFF_SIZE_MACRO, MAX_BUFF_SIZE_VALUE);
326     sb.Append("#endif\n\n");
327 
328     sb.AppendFormat("#ifndef %s\n", CHECK_VALUE_RETURN_MACRO);
329     sb.AppendFormat("#define %s(lv, compare, rv, ret) do { \\\n", CHECK_VALUE_RETURN_MACRO);
330     sb.Append(TAB).Append("if ((lv) compare (rv)) { \\\n");
331     sb.Append(TAB).Append(TAB).Append("return ret; \\\n");
332     sb.Append(TAB).Append("} \\\n");
333     sb.Append("} while (false)\n");
334     sb.Append("#endif\n\n");
335 
336     sb.AppendFormat("#ifndef %s\n", CHECK_VALUE_RET_GOTO_MACRO);
337     sb.AppendFormat("#define %s(lv, compare, rv, ret, value, table) do { \\\n", CHECK_VALUE_RET_GOTO_MACRO);
338     sb.Append(TAB).Append("if ((lv) compare (rv)) { \\\n");
339     sb.Append(TAB).Append(TAB).Append("ret = value; \\\n");
340     sb.Append(TAB).Append(TAB).Append("goto table; \\\n");
341     sb.Append(TAB).Append("} \\\n");
342     sb.Append("} while (false)\n");
343     sb.Append("#endif\n");
344 }
345 } // namespace Idl
346 } // namespace OHOS
347