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 <unistd.h>
17 #include <sys/stat.h>
18 #include "sa_code_emitter.h"
19 #include "ast/ast_map_type.h"
20 #include "ast/ast_orderedmap_type.h"
21 #include "ast/ast_set_type.h"
22 #include "type/sa_boolean_type_emitter.h"
23 #include "type/sa_byte_type_emitter.h"
24 #include "type/sa_short_type_emitter.h"
25 #include "type/sa_int_type_emitter.h"
26 #include "type/sa_long_type_emitter.h"
27 #include "type/sa_float_type_emitter.h"
28 #include "type/sa_double_type_emitter.h"
29 #include "type/sa_char_type_emitter.h"
30 #include "type/sa_cstring_type_emitter.h"
31 #include "type/sa_string_type_emitter.h"
32 #include "type/sa_u16string_type_emitter.h"
33 #include "type/sa_seq_type_emitter.h"
34 #include "type/sa_set_type_emitter.h"
35 #include "type/sa_rawdata_type_emitter.h"
36 #include "type/sa_interface_type_emitter.h"
37 #include "type/sa_map_type_emitter.h"
38 #include "type/sa_orderedmap_type_emitter.h"
39 #include "type/sa_array_type_emitter.h"
40 #include "type/sa_ptr_type_emitter.h"
41 #include "type/sa_uchar_type_emitter.h"
42 #include "type/sa_uint_type_emitter.h"
43 #include "type/sa_ulong_type_emitter.h"
44 #include "type/sa_ushort_type_emitter.h"
45 #include "type/sa_fd_type_emitter.h"
46 #include "type/sa_fdsan_type_emitter.h"
47 #include "type/sa_enum_type_emitter.h"
48 #include "type/sa_struct_type_emitter.h"
49 #include "type/sa_union_type_emitter.h"
50 #include "util/file.h"
51 #include "util/options.h"
52 #include "util/logger.h"
53 #include "util/string_helper.h"
54
55 namespace OHOS {
56 namespace Idl {
57 SACodeEmitter::TypeEmitterMap SACodeEmitter::basicEmitters_ = {
58 {TypeKind::TYPE_BOOLEAN, new SaBooleanTypeEmitter() },
59 {TypeKind::TYPE_BYTE, new SaByteTypeEmitter() },
60 {TypeKind::TYPE_SHORT, new SaShortTypeEmitter() },
61 {TypeKind::TYPE_INT, new SaIntTypeEmitter() },
62 {TypeKind::TYPE_LONG, new SaLongTypeEmitter() },
63 {TypeKind::TYPE_FLOAT, new SaFloatTypeEmitter() },
64 {TypeKind::TYPE_DOUBLE, new SaDoubleTypeEmitter() },
65 {TypeKind::TYPE_CHAR, new SaCharTypeEmitter() },
66 {TypeKind::TYPE_CSTRING, new SaCStringTypeEmitter() },
67 {TypeKind::TYPE_STRING, new SaStringTypeEmitter() },
68 {TypeKind::TYPE_U16STRING, new SaU16stringTypeEmitter() },
69 {TypeKind::TYPE_UCHAR, new SaUcharTypeEmitter() },
70 {TypeKind::TYPE_UINT, new SaUintTypeEmitter() },
71 {TypeKind::TYPE_ULONG, new SaUlongTypeEmitter() },
72 {TypeKind::TYPE_USHORT, new SaUshortTypeEmitter() },
73 {TypeKind::TYPE_FILEDESCRIPTOR, new SaFdTypeEmitter() },
74 {TypeKind::TYPE_FILEDESCRIPTORSAN, new SaFdSanTypeEmitter() },
75 };
76
OutPut(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)77 bool SACodeEmitter::OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
78 {
79 if (!Reset(ast, targetDirectory, mode)) {
80 return false;
81 }
82
83 EmitCode();
84 return true;
85 }
86
Reset(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)87 bool SACodeEmitter::Reset(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
88 {
89 if ((ast == nullptr) || targetDirectory.empty()) {
90 return false;
91 }
92
93 CleanData();
94
95 ast_ = ast;
96 for (auto interface : ast_->GetInterfaceDefs()) {
97 if (interface->IsExternal() == false) {
98 interface_ = interface;
99 break;
100 }
101 }
102 if (interface_ != nullptr) {
103 interfaceName_ = interface_->GetName();
104 interfaceFullName_ = interface_->GetNamespace()->ToString() + interfaceName_;
105 baseName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_;
106 proxyName_ = baseName_ + "Proxy";
107 proxyFullName_ = interface_->GetNamespace()->ToString() + proxyName_;
108
109 stubName_ = baseName_ + "Stub";
110 stubFullName_ = interface_->GetNamespace()->ToString() + stubName_;
111
112 clientName_ = baseName_ + "Client";
113 clientFullName_ = interface_->GetNamespace()->ToString() + clientName_;
114 deathRecipientName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) + "Recipient" :
115 interfaceName_ + "Recipient";
116 } else if (ast_->GetASTFileType() == ASTFileType::AST_TYPES) {
117 baseName_ = ast_->GetName();
118 }
119
120 if (!ResolveDirectory(targetDirectory)) {
121 return false;
122 }
123
124 return true;
125 }
126
CleanData()127 void SACodeEmitter::CleanData()
128 {
129 Options &options = Options::GetInstance();
130
131 domainId_ = options.GetDomainId();
132 logTag_ = options.GetLogTag();
133 hitraceTag_ = options.GetGenerateHitraceTag();
134 hitraceOn_ = options.DoHitraceState();
135 logOn_ = options.DoLogOn();
136 SaTypeEmitter::logOn_ = logOn_;
137 SaTypeEmitter::domainId_ = domainId_;
138 ast_ = nullptr;
139 interface_ = nullptr;
140 directory_ = "";
141 interfaceName_ = "";
142 interfaceFullName_ = "";
143 baseName_ = "";
144 proxyName_ = "";
145 proxyFullName_ = "";
146 stubName_ = "";
147 stubFullName_ = "";
148 clientName_ = "";
149 clientFullName_ = "";
150 }
151
ResolveDirectory(const std::string & targetDirectory)152 bool SACodeEmitter::ResolveDirectory(const std::string &targetDirectory)
153 {
154 directory_ = targetDirectory;
155 #ifdef __MINGW32__
156 if (targetDirectory.find(":\\") == std::string::npos) {
157 char* cwd = getcwd(nullptr, 0);
158 directory_ = StringHelper::Format("%s\\%s", cwd, targetDirectory.c_str());
159 free(cwd);
160 }
161 #else
162 if (!StringHelper::StartWith(targetDirectory, "/")) {
163 char* cwd = getcwd(nullptr, 0);
164 directory_ = StringHelper::Format("%s/%s", cwd, targetDirectory.c_str());
165 free(cwd);
166 }
167 #endif
168
169 if (!access(directory_.c_str(), R_OK | W_OK)) {
170 return true;
171 }
172
173 #ifdef __MINGW32__
174 if (mkdir(directory_.c_str()) != 0) {
175 #else
176 if (mkdir(directory_.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) != 0) {
177 #endif
178 Logger::E(TAG, "Create \"%s\" directory failed.", directory_.c_str());
179 return false;
180 }
181
182 return true;
183 }
184
185 AutoPtr<SaTypeEmitter> SACodeEmitter::GetTypeEmitter(AutoPtr<ASTType> astType) const
186 {
187 AutoPtr<SaTypeEmitter> typeEmitter;
188 auto basicTypePair = basicEmitters_.find(astType->GetTypeKind());
189 if (basicTypePair != basicEmitters_.end()) {
190 typeEmitter = (static_cast<SaTypeEmitter*>(basicTypePair->second.Get()));
191 }
192
193 if (typeEmitter == nullptr) {
194 typeEmitter = NewTypeEmitter(astType);
195 }
196
197 if (astType->IsSequenceableType() || astType->IsInterfaceType() || astType->IsRawDataType()) {
198 typeEmitter->SetTypeName(astType->ToShortString());
199 } else if (astType->IsEnumType() || astType->IsStructType() || astType->IsUnionType()) {
200 typeEmitter->SetTypeName(astType->GetName());
201 } else {
202 typeEmitter->SetTypeName(astType->ToString());
203 }
204 return typeEmitter;
205 }
206
207 std::string SACodeEmitter::GetNameWithNamespace(AutoPtr<ASTNamespace> space, const std::string name) const
208 {
209 std::vector<std::string> namespaceVec = StringHelper::Split(space->ToString(), ".");
210 std::vector<std::string> result;
211
212 std::string rootPackage = Options::GetInstance().GetRootPackage(space->ToString());
213 size_t rootPackageNum = StringHelper::Split(rootPackage, ".").size();
214
215 for (size_t i = 0; i < namespaceVec.size(); i++) {
216 std::string ns;
217 if (i < rootPackageNum) {
218 ns = StringHelper::StrToUpper(namespaceVec[i]);
219 } else {
220 ns = PascalName(namespaceVec[i]);
221 }
222
223 result.emplace_back(ns);
224 }
225 StringBuilder sb;
226 for (const auto &ns : result) {
227 sb.AppendFormat("%s::", ns.c_str());
228 }
229 sb.Append(name);
230 return sb.ToString();
231 }
232
233 AutoPtr<SaTypeEmitter> SACodeEmitter::NewTypeEmitter(AutoPtr<ASTType> astType) const
234 {
235 switch (astType->GetTypeKind()) {
236 case TypeKind::TYPE_MAP:
237 return NewMapTypeEmitter(astType);
238 case TypeKind::TYPE_ORDEREDMAP:
239 return NewOrderedMapTypeEmitter(astType);
240 case TypeKind::TYPE_ARRAY:
241 return NewArrayTypeEmitter(astType);
242 case TypeKind::TYPE_LIST:
243 return NewListTypeEmitter(astType);
244 case TypeKind::TYPE_SET:
245 return NewSetTypeEmitter(astType);
246 case TypeKind::TYPE_SHAREDPTR:
247 case TypeKind::TYPE_UNIQUEPTR:
248 case TypeKind::TYPE_SPTR:
249 case TypeKind::TYPE_NULL_SHAREDPTR:
250 case TypeKind::TYPE_NULL_UNIQUEPTR:
251 case TypeKind::TYPE_NULL_SPTR:
252 return NewPtrTypeEmitter(astType, astType->GetTypeKind());
253 case TypeKind::TYPE_ENUM:
254 return NewEnumTypeEmitter(astType);
255 case TypeKind::TYPE_STRUCT:
256 return NewStructTypeEmitter(astType);
257 case TypeKind::TYPE_UNION:
258 return NewUnionTypeEmitter(astType);
259 case TypeKind::TYPE_SEQUENCEABLE:
260 return new SaSeqTypeEmitter();
261 case TypeKind::TYPE_RAWDATA:
262 return new SaRawDataTypeEmitter();
263 case TypeKind::TYPE_INTERFACE:
264 return new SaInterfaceTypeEmitter();
265 default: {
266 // type not match, new a empty emitter
267 AutoPtr<SaTypeEmitter> typeEmitter = new SaTypeEmitter();
268 return typeEmitter;
269 }
270 }
271 }
272
273 AutoPtr<SaTypeEmitter> SACodeEmitter::NewMapTypeEmitter(AutoPtr<ASTType> astType) const
274 {
275 AutoPtr<SaMapTypeEmitter> mapTypeEmitter = new SaMapTypeEmitter();
276 AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(astType.Get()))->GetKeyType();
277 AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(astType.Get()))->GetValueType();
278 AutoPtr<SaTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
279 AutoPtr<SaTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
280 mapTypeEmitter->SetKeyEmitter(keyEmitter);
281 mapTypeEmitter->SetValueEmitter(valueEmitter);
282 return mapTypeEmitter.Get();
283 }
284
285 AutoPtr<SaTypeEmitter> SACodeEmitter::NewOrderedMapTypeEmitter(AutoPtr<ASTType> astType) const
286 {
287 AutoPtr<SaOrderedMapTypeEmitter> orderedmapTypeEmitter = new SaOrderedMapTypeEmitter();
288 AutoPtr<ASTType> keyType = (static_cast<ASTOrderedMapType*>(astType.Get()))->GetKeyType();
289 AutoPtr<ASTType> valueType = (static_cast<ASTOrderedMapType*>(astType.Get()))->GetValueType();
290 AutoPtr<SaTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
291 AutoPtr<SaTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
292 orderedmapTypeEmitter->SetKeyEmitter(keyEmitter);
293 orderedmapTypeEmitter->SetValueEmitter(valueEmitter);
294 return orderedmapTypeEmitter.Get();
295 }
296
297 AutoPtr<SaTypeEmitter> SACodeEmitter::NewArrayTypeEmitter(AutoPtr<ASTType> astType) const
298 {
299 AutoPtr<SaArrayTypeEmitter> arrayTypeEmitter = new SaArrayTypeEmitter();
300 AutoPtr<ASTType> elemType = (static_cast<ASTArrayType*>(astType.Get()))->GetElementType();
301 AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
302 arrayTypeEmitter->SetElementEmitter(elemEmitter);
303 return arrayTypeEmitter.Get();
304 }
305
306 AutoPtr<SaTypeEmitter> SACodeEmitter::NewListTypeEmitter(AutoPtr<ASTType> astType) const
307 {
308 AutoPtr<SaListTypeEmitter> listTypeEmitter = new SaListTypeEmitter();
309 AutoPtr<ASTType> elemType = (static_cast<ASTListType*>(astType.Get()))->GetElementType();
310 AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
311 listTypeEmitter->SetElementEmitter(elemEmitter);
312 return listTypeEmitter.Get();
313 }
314
315 AutoPtr<SaTypeEmitter> SACodeEmitter::NewSetTypeEmitter(AutoPtr<ASTType> astType) const
316 {
317 AutoPtr<SaSetTypeEmitter> setTypeEmitter = new SaSetTypeEmitter();
318 AutoPtr<ASTType> elemType = (static_cast<ASTSetType*>(astType.Get()))->GetElementType();
319 AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
320 setTypeEmitter->SetElementEmitter(elemEmitter);
321 return setTypeEmitter.Get();
322 }
323
324 AutoPtr<SaTypeEmitter> SACodeEmitter::NewPtrTypeEmitter(AutoPtr<ASTType> astType, TypeKind kind) const
325 {
326 AutoPtr<SaPtrTypeEmitter> ptrTypeEmitter = new SaPtrTypeEmitter(kind);
327 AutoPtr<ASTType> elemType = (static_cast<ASTPtrType*>(astType.Get()))->GetElementType();
328 AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
329 ptrTypeEmitter->SetElementEmitter(elemEmitter);
330 return ptrTypeEmitter.Get();
331 }
332
333 AutoPtr<SaTypeEmitter> SACodeEmitter::NewEnumTypeEmitter(AutoPtr<ASTType> astType) const
334 {
335 AutoPtr<SaEnumTypeEmitter> enumTypeEmitter = new SaEnumTypeEmitter();
336 AutoPtr<ASTEnumType> enumType = static_cast<ASTEnumType*>(astType.Get());
337 if (enumType->GetBaseType() != nullptr) {
338 AutoPtr<SaTypeEmitter> baseTypeEmitter = GetTypeEmitter(enumType->GetBaseType());
339 enumTypeEmitter->SetBaseTypeName(baseTypeEmitter->EmitCppType());
340 }
341 for (auto it : enumType->GetMembers()) {
342 if (it->GetExprValue() == nullptr) {
343 enumTypeEmitter->AddMember(new SaEnumValueEmitter(it->GetName(), std::string("")));
344 } else {
345 enumTypeEmitter->AddMember(new SaEnumValueEmitter(it->GetName(), it->GetExprValue()->EmitCode()));
346 }
347 }
348 return enumTypeEmitter.Get();
349 }
350
351 AutoPtr<SaTypeEmitter> SACodeEmitter::NewStructTypeEmitter(AutoPtr<ASTType> astType) const
352 {
353 AutoPtr<SaStructTypeEmitter> structTypeEmitter = new SaStructTypeEmitter();
354 AutoPtr<ASTStructType> structType = (static_cast<ASTStructType*>(astType.Get()));
355 for (auto it : structType->GetMembers()) {
356 structTypeEmitter->AddMember(std::get<0>(it), GetTypeEmitter(std::get<1>(it)));
357 }
358 return structTypeEmitter.Get();
359 }
360
361 AutoPtr<SaTypeEmitter> SACodeEmitter::NewUnionTypeEmitter(AutoPtr<ASTType> astType) const
362 {
363 AutoPtr<SaUnionTypeEmitter> unionTypeEmitter = new SaUnionTypeEmitter();
364 AutoPtr<ASTUnionType> unionType = (static_cast<ASTUnionType*>(astType.Get()));
365 for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
366 unionTypeEmitter->AddMember(unionType->GetMemberName(i), GetTypeEmitter(unionType->GetMemberType(i)));
367 }
368 return unionTypeEmitter.Get();
369 }
370 } // namespace Idl
371 } // namespace OHOS
372