1 /*
2 * Copyright (c) 2021 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/cpp_interface_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const String & targetDirectory)15 bool CppInterfaceCodeEmitter::ResolveDirectory(const String& targetDirectory)
16 {
17 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE ||
18 ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
19 directory_ = GetFilePath(targetDirectory);
20 } else {
21 return false;
22 }
23
24 if (!File::CreateParentDir(directory_)) {
25 Logger::E("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.string());
26 return false;
27 }
28
29 return true;
30 }
31
EmitCode()32 void CppInterfaceCodeEmitter::EmitCode()
33 {
34 EmitInterfaceHeaderFile();
35 }
36
EmitInterfaceHeaderFile()37 void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile()
38 {
39 String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string());
40 File file(filePath, File::WRITE);
41 StringBuilder sb;
42
43 EmitLicense(sb);
44 EmitHeadMacro(sb, interfaceFullName_);
45 sb.Append("\n");
46 EmitInterfaceInclusions(sb);
47 sb.Append("\n");
48 EmitInterfaceVersionMacro(sb);
49 sb.Append("\n");
50 EmitInterfaceBuffSizeMacro(sb);
51 sb.Append("\n");
52 EmitBeginNamespace(sb);
53 EmitUsingNamespace(sb);
54 sb.Append("\n");
55 EmitInterfaceMethodCommands(sb, "");
56 sb.Append("\n");
57 EmitInterfaceDefinition(sb);
58 EmitEndNamespace(sb);
59 sb.Append("\n");
60 EmitTailMacro(sb, interfaceFullName_);
61
62 String data = sb.ToString();
63 file.WriteData(data.string(), data.GetLength());
64 file.Flush();
65 file.Close();
66 }
67
EmitInterfaceInclusions(StringBuilder & sb)68 void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder& sb)
69 {
70 HeaderFile::HeaderFileSet headerFiles;
71
72 GetStdlibInclusions(headerFiles);
73 GetImportInclusions(headerFiles);
74 GetHeaderOtherLibInclusions(headerFiles);
75
76 for (const auto& file : headerFiles) {
77 sb.AppendFormat("%s\n", file.ToString().string());
78 }
79 }
80
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)81 void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles)
82 {
83 headerFiles.emplace(HeaderFile(HeaderFileType::C_STD_HEADER_FILE, "stdint"));
84 headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iremote_broker"));
85 }
86
EmitInterfaceVersionMacro(StringBuilder & sb)87 void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder& sb)
88 {
89 sb.AppendFormat("#define %s %u\n", majorVerName_.string(), ast_->GetMajorVer());
90 sb.AppendFormat("#define %s %u\n", minorVerName_.string(), ast_->GetMinorVer());
91 }
92
EmitInterfaceDefinition(StringBuilder & sb)93 void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb)
94 {
95 if (!interface_->IsSerializable()) {
96 sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string());
97 sb.Append("public:\n");
98 EmitInterfaceDescriptor(sb, g_tab);
99 sb.Append("\n");
100 EmitInterfaceDestruction(sb, g_tab);
101 sb.Append("\n");
102 EmitGetMethodDecl(sb, g_tab);
103 sb.Append("\n");
104 EmitGetInstanceMethodDecl(sb, g_tab);
105 sb.Append("\n");
106 EmitInterfaceMethodsDecl(sb, g_tab);
107 sb.Append("};\n");
108 } else {
109 sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string());
110 sb.Append("public:\n");
111 EmitInterfaceDescriptor(sb, g_tab);
112 sb.Append("\n");
113 EmitInterfaceDestruction(sb, g_tab);
114 sb.Append("\n");
115 EmitInterfaceMethodsDecl(sb, g_tab);
116 sb.Append("};\n");
117 }
118 }
119
EmitInterfaceDescriptor(StringBuilder & sb,const String & prefix)120 void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder& sb, const String& prefix)
121 {
122 sb.Append(g_tab).AppendFormat("DECLARE_INTERFACE_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.string());
123 }
124
EmitGetMethodDecl(StringBuilder & sb,const String & prefix)125 void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder& sb, const String& prefix)
126 {
127 sb.Append(prefix).AppendFormat("static sptr<%s> Get();\n", interface_->GetName().string());
128 }
129
EmitGetInstanceMethodDecl(StringBuilder & sb,const String & prefix)130 void CppInterfaceCodeEmitter::EmitGetInstanceMethodDecl(StringBuilder& sb, const String& prefix)
131 {
132 sb.Append(prefix).AppendFormat("static sptr<%s> GetInstance(const std::string& serviceName);\n",
133 interface_->GetName().string());
134 }
135
EmitInterfaceDestruction(StringBuilder & sb,const String & prefix)136 void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder& sb, const String& prefix)
137 {
138 sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().string());
139 }
140
EmitInterfaceMethodsDecl(StringBuilder & sb,const String & prefix)141 void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder& sb, const String& prefix)
142 {
143 for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
144 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
145 EmitInterfaceMethodDecl(method, sb, prefix);
146 sb.Append("\n");
147 }
148
149 EmitInterfaceMethodDecl(interface_->GetVersionMethod(), sb, prefix);
150 }
151
EmitInterfaceMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)152 void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
153 const String& prefix)
154 {
155 if (method->GetParameterNumber() == 0) {
156 sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().string());
157 } else {
158 StringBuilder paramStr;
159 paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().string());
160 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
161 AutoPtr<ASTParameter> param = method->GetParameter(i);
162 EmitInterfaceMethodParameter(param, paramStr, "");
163 if (i + 1 < method->GetParameterNumber()) {
164 paramStr.Append(", ");
165 }
166 }
167
168 paramStr.Append(") = 0;");
169 sb.Append(SpecificationParam(paramStr, prefix + g_tab));
170 sb.Append("\n");
171 }
172 }
173
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const String & prefix)174 void CppInterfaceCodeEmitter::EmitInterfaceMethodParameter(const AutoPtr<ASTParameter>& param, StringBuilder& sb,
175 const String& prefix)
176 {
177 sb.Append(prefix).Append(param->EmitCppParameter());
178 }
179 } // namespace HDI
180 } // namespace OHOS