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