1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "codegen/code_generator.h"
10 #include "codegen/c_client_proxy_code_emitter.h"
11 #include "codegen/c_custom_types_code_emitter.h"
12 #include "codegen/c_interface_code_emitter.h"
13 #include "codegen/c_service_driver_code_emitter.h"
14 #include "codegen/c_service_impl_code_emitter.h"
15 #include "codegen/c_service_stub_code_emitter.h"
16 #include "codegen/cpp_client_proxy_code_emitter.h"
17 #include "codegen/cpp_custom_types_code_emitter.h"
18 #include "codegen/cpp_interface_code_emitter.h"
19 #include "codegen/cpp_service_driver_code_emitter.h"
20 #include "codegen/cpp_service_impl_code_emitter.h"
21 #include "codegen/cpp_service_stub_code_emitter.h"
22 #include "codegen/java_client_interface_code_emitter.h"
23 #include "codegen/java_client_proxy_code_emitter.h"
24 #include "util/options.h"
25 #include "util/logger.h"
26
27 namespace OHOS {
28 namespace HDI {
29 GeneratePolicies CodeGenerator::policies_ = {
30 {
31 SystemLevel::MINI,
32 {
33 {
34 GenMode::LOW,
35 {
36 {Language::C, CodeGenerator::GenLowCCode}
37 }
38 }
39 }
40 },
41 {
42 SystemLevel::LITE,
43 {
44 {
45 GenMode::KERNEL,
46 {
47 {Language::C, CodeGenerator::GenKernelCode}
48 }
49 },
50 {
51 GenMode::PASSTHROUGH,
52 {
53 {Language::C, CodeGenerator::GenPassthroughCCode},
54 {Language::CPP, CodeGenerator::GenPassthroughCppCode}
55 }
56 }
57 }
58 },
59 {
60 SystemLevel::FULL,
61 {
62 {
63 GenMode::KERNEL,
64 {
65 {Language::C, CodeGenerator::GenKernelCode}
66 }
67 },
68 {
69 GenMode::PASSTHROUGH,
70 {
71 {Language::C, CodeGenerator::GenPassthroughCCode},
72 {Language::CPP, CodeGenerator::GenPassthroughCppCode}
73 }
74 },
75 {
76 GenMode::IPC,
77 {
78 {Language::C, CodeGenerator::GenIpcCCode},
79 {Language::CPP, CodeGenerator::GenIpcCppCode},
80 {Language::JAVA, CodeGenerator::GenIpcJavaCode}
81 }
82 }
83 }
84 }
85 };
86
87 CodeEmitMap CodeGenerator::cCodeEmitters_ = {
88 {"types", new CCustomTypesCodeEmitter() },
89 {"interface", new CInterfaceCodeEmitter() },
90 {"proxy", new CClientProxyCodeEmitter() },
91 {"driver", new CServiceDriverCodeEmitter()},
92 {"stub", new CServiceStubCodeEmitter() },
93 {"service", new CServiceImplCodeEmitter() },
94 };
95
96 CodeEmitMap CodeGenerator::cppCodeEmitters_ = {
97 {"types", new CppCustomTypesCodeEmitter() },
98 {"interface", new CppInterfaceCodeEmitter() },
99 {"proxy", new CppClientProxyCodeEmitter() },
100 {"driver", new CppServiceDriverCodeEmitter()},
101 {"stub", new CppServiceStubCodeEmitter() },
102 {"service", new CppServiceImplCodeEmitter() },
103 };
104
105 CodeEmitMap CodeGenerator::javaCodeEmitters_ = {
106 {"interface", new JavaClientInterfaceCodeEmitter()},
107 {"proxy", new JavaClientProxyCodeEmitter() },
108 };
109
Generate(const StrAstMap & allAst)110 bool CodeGenerator::Generate(const StrAstMap &allAst)
111 {
112 auto genCodeFunc = GetCodeGenPoilcy();
113 if (!genCodeFunc) {
114 return false;
115 }
116
117 std::string outDir = Options::GetInstance().GetGenerationDirectory();
118 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
119 Language language = Options::GetInstance().GetLanguage();
120 if (language == Language::CPP) {
121 for (const auto &ast : allAst) {
122 if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
123 genCodeFunc(ast.second, outDir);
124 }
125 }
126 } else if (language == Language::C) {
127 for (const auto &ast : allAst) {
128 genCodeFunc(ast.second, outDir);
129 }
130 }
131
132 return true;
133 }
134
GetCodeGenPoilcy()135 CodeGenFunc CodeGenerator::GetCodeGenPoilcy()
136 {
137 auto systemPolicies = policies_.find(Options::GetInstance().GetSystemLevel());
138 if (systemPolicies == policies_.end()) {
139 Logger::E(TAG, "the system level is not supported, please check option");
140 return CodeGenFunc{};
141 }
142
143 auto genModePolicies = systemPolicies->second;
144 auto genModeIter = genModePolicies.find(Options::GetInstance().GetGenMode());
145 if (genModeIter == genModePolicies.end()) {
146 Logger::E(TAG, "the generate mode is not supported, please check option");
147 return CodeGenFunc{};
148 }
149
150 auto languagePolicies = genModeIter->second;
151 auto languageIter = languagePolicies.find(Options::GetInstance().GetLanguage());
152 if (languageIter == languagePolicies.end()) {
153 Logger::E(TAG, "the language is not supported, please check option");
154 return CodeGenFunc{};
155 }
156 return languageIter->second;
157 }
158
GenIpcCCode(const AutoPtr<AST> & ast,const std::string & outDir)159 void CodeGenerator::GenIpcCCode(const AutoPtr<AST> &ast, const std::string &outDir)
160 {
161 GenMode mode = GenMode::IPC;
162 switch (ast->GetASTFileType()) {
163 case ASTFileType::AST_TYPES: {
164 cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
165 break;
166 }
167 case ASTFileType::AST_IFACE: {
168 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
169 cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
170 cCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
171 cCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
172 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
173 break;
174 }
175 case ASTFileType::AST_ICALLBACK: {
176 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
177 cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
178 cCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
179 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
180 break;
181 }
182 default:
183 break;
184 }
185 }
186
GenIpcCppCode(const AutoPtr<AST> & ast,const std::string & outDir)187 void CodeGenerator::GenIpcCppCode(const AutoPtr<AST> &ast, const std::string &outDir)
188 {
189 GenMode mode = GenMode::IPC;
190 switch (ast->GetASTFileType()) {
191 case ASTFileType::AST_TYPES: {
192 cppCodeEmitters_["types"]->OutPut(ast, outDir, mode);
193 break;
194 }
195 case ASTFileType::AST_IFACE: {
196 cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
197 cppCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
198 cppCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
199 cppCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
200 cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
201 break;
202 }
203 case ASTFileType::AST_ICALLBACK: {
204 cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
205 cppCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
206 cppCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
207 cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
208 break;
209 }
210 default:
211 break;
212 }
213 }
214
GenIpcJavaCode(const AutoPtr<AST> & ast,const std::string & outDir)215 void CodeGenerator::GenIpcJavaCode(const AutoPtr<AST> &ast, const std::string &outDir)
216 {
217 GenMode mode = GenMode::IPC;
218 switch (ast->GetASTFileType()) {
219 case ASTFileType::AST_TYPES: {
220 javaCodeEmitters_["types"]->OutPut(ast, outDir, mode);
221 break;
222 }
223 case ASTFileType::AST_IFACE:
224 case ASTFileType::AST_ICALLBACK: {
225 javaCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
226 javaCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
227 break;
228 }
229 default:
230 break;
231 }
232 }
233
GenPassthroughCCode(const AutoPtr<AST> & ast,const std::string & outDir)234 void CodeGenerator::GenPassthroughCCode(const AutoPtr<AST> &ast, const std::string &outDir)
235 {
236 GenMode mode = GenMode::PASSTHROUGH;
237 switch (ast->GetASTFileType()) {
238 case ASTFileType::AST_TYPES: {
239 cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
240 break;
241 }
242 case ASTFileType::AST_IFACE: {
243 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
244 cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
245 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
246 break;
247 }
248 case ASTFileType::AST_ICALLBACK: {
249 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
250 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
251 break;
252 }
253 default:
254 break;
255 }
256 }
257
GenPassthroughCppCode(const AutoPtr<AST> & ast,const std::string & outDir)258 void CodeGenerator::GenPassthroughCppCode(const AutoPtr<AST> &ast, const std::string &outDir)
259 {
260 GenMode mode = GenMode::PASSTHROUGH;
261 switch (ast->GetASTFileType()) {
262 case ASTFileType::AST_TYPES: {
263 cppCodeEmitters_["types"]->OutPut(ast, outDir, mode);
264 break;
265 }
266 case ASTFileType::AST_IFACE: {
267 cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
268 cppCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
269 cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
270 break;
271 }
272 case ASTFileType::AST_ICALLBACK: {
273 cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
274 cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
275 break;
276 }
277 default:
278 break;
279 }
280 }
281
GenKernelCode(const AutoPtr<AST> & ast,const std::string & outDir)282 void CodeGenerator::GenKernelCode(const AutoPtr<AST> &ast, const std::string &outDir)
283 {
284 GenMode mode = GenMode::KERNEL;
285 switch (ast->GetASTFileType()) {
286 case ASTFileType::AST_TYPES: {
287 cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
288 break;
289 }
290 case ASTFileType::AST_IFACE: {
291 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
292 cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
293 cCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
294 cCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
295 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
296 break;
297 }
298 default:
299 break;
300 }
301 }
302
GenLowCCode(const AutoPtr<AST> & ast,const std::string & outDir)303 void CodeGenerator::GenLowCCode(const AutoPtr<AST> &ast, const std::string &outDir)
304 {
305 GenMode mode = GenMode::LOW;
306 switch (ast->GetASTFileType()) {
307 case ASTFileType::AST_TYPES: {
308 cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
309 break;
310 }
311 case ASTFileType::AST_IFACE: {
312 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
313 cCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
314 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
315 break;
316 }
317 case ASTFileType::AST_ICALLBACK: {
318 cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
319 cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
320 break;
321 }
322 default:
323 break;
324 }
325 }
326 } // namespace HDI
327 } // namespace OHOS