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