• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cpp_service_impl_code_emitter.h"
17 #include "util/file.h"
18 #include "util/logger.h"
19 
20 namespace OHOS {
21 namespace Idl {
ResolveDirectory(const std::string & targetDirectory)22 bool CppServiceImplCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
23 {
24     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
25         directory_ = GetFileParentPath(targetDirectory);
26     } else {
27         return false;
28     }
29 
30     if (!File::CreateParentDir(directory_)) {
31         Logger::E("CppServiceImplCodeEmitter", "Create '%s' failed!", directory_.c_str());
32         return false;
33     }
34 
35     return true;
36 }
37 
EmitCode()38 void CppServiceImplCodeEmitter::EmitCode()
39 {
40     switch (mode_) {
41         case GenMode::PASSTHROUGH:
42         case GenMode::IPC: {
43             EmitImplHeaderFile();
44             EmitImplSourceFile();
45             break;
46         }
47         default:
48             break;
49     }
50 }
51 
EmitImplHeaderFile()52 void CppServiceImplCodeEmitter::EmitImplHeaderFile()
53 {
54     std::string filePath =
55         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(implName_).c_str()));
56     File file(filePath, File::WRITE);
57     StringBuilder sb;
58 
59     EmitLicense(sb);
60     EmitHeadMacro(sb, implFullName_);
61     sb.Append("\n");
62     EmitServiceImplInclusions(sb);
63     sb.Append("\n");
64     EmitServiceImplDecl(sb);
65     sb.Append("\n");
66     EmitTailMacro(sb, implFullName_);
67 
68     std::string data = sb.ToString();
69     file.WriteData(data.c_str(), data.size());
70     file.Flush();
71     file.Close();
72 }
73 
EmitServiceImplInclusions(StringBuilder & sb)74 void CppServiceImplCodeEmitter::EmitServiceImplInclusions(StringBuilder &sb)
75 {
76     HeaderFile::HeaderFileSet headerFiles;
77     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
78 
79     for (const auto &file : headerFiles) {
80         sb.AppendFormat("%s\n", file.ToString().c_str());
81     }
82 }
83 
EmitServiceImplDecl(StringBuilder & sb)84 void CppServiceImplCodeEmitter::EmitServiceImplDecl(StringBuilder &sb)
85 {
86     EmitBeginNamespace(sb);
87     sb.AppendFormat("class %sService : public %s {\n", baseName_.c_str(),
88         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
89     sb.Append("public:\n");
90     EmitServiceImplBody(sb, TAB);
91     sb.Append("};\n");
92     EmitEndNamespace(sb);
93 }
94 
EmitServiceImplBody(StringBuilder & sb,const std::string & prefix)95 void CppServiceImplCodeEmitter::EmitServiceImplBody(StringBuilder &sb, const std::string &prefix)
96 {
97     (void)prefix;
98     EmitServiceImplConstructor(sb, TAB);
99     sb.Append("\n");
100     EmitServiceImplMethodDecls(sb, TAB);
101 }
102 
EmitServiceImplConstructor(StringBuilder & sb,const std::string & prefix) const103 void CppServiceImplCodeEmitter::EmitServiceImplConstructor(StringBuilder &sb, const std::string &prefix) const
104 {
105     sb.Append(prefix).AppendFormat("%s() = default;\n", implName_.c_str());
106     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", implName_.c_str());
107 }
108 
EmitServiceImplMethodDecls(StringBuilder & sb,const std::string & prefix) const109 void CppServiceImplCodeEmitter::EmitServiceImplMethodDecls(StringBuilder &sb, const std::string &prefix) const
110 {
111     AutoPtr<ASTInterfaceType> interface = interface_;
112     while (interface != nullptr) {
113         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
114             EmitServiceImplMethodDecl(method, sb, prefix);
115             sb.Append("\n");
116         }
117         interface = interface->GetExtendsInterface();
118     }
119 }
120 
EmitServiceImplMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const121 void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(
122     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
123 {
124     if (method->GetParameterNumber() == 0) {
125         sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
126     } else {
127         StringBuilder paramStr;
128         paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
129         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
130             AutoPtr<ASTParameter> param = method->GetParameter(i);
131             EmitInterfaceMethodParameter(param, paramStr, "");
132             if (i + 1 < method->GetParameterNumber()) {
133                 paramStr.Append(", ");
134             }
135         }
136 
137         paramStr.Append(") override;");
138 
139         sb.Append(SpecificationParam(paramStr, prefix + TAB));
140         sb.Append("\n");
141     }
142 }
143 
EmitImplSourceFile()144 void CppServiceImplCodeEmitter::EmitImplSourceFile()
145 {
146     std::string filePath = File::AdapterPath(
147         StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(implName_).c_str()));
148     File file(filePath, File::WRITE);
149     StringBuilder sb;
150 
151     EmitLicense(sb);
152     EmitImplSourceInclusions(sb);
153     sb.Append("\n");
154     EmitLogTagMacro(sb, FileName(implName_));
155     sb.Append("\n");
156     EmitBeginNamespace(sb);
157     EmitServiceImplGetMethodImpl(sb, "");
158     EmitServiceImplMethodImpls(sb, "");
159     EmitEndNamespace(sb);
160 
161     std::string data = sb.ToString();
162     file.WriteData(data.c_str(), data.size());
163     file.Flush();
164     file.Close();
165 }
166 
EmitImplSourceInclusions(StringBuilder & sb)167 void CppServiceImplCodeEmitter::EmitImplSourceInclusions(StringBuilder &sb)
168 {
169     HeaderFile::HeaderFileSet headerFiles;
170     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(implName_));
171     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
172 
173     for (const auto &file : headerFiles) {
174         sb.AppendFormat("%s\n", file.ToString().c_str());
175     }
176 }
177 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const178 void CppServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
179 {
180     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
181 }
182 
EmitServiceImplMethodImpls(StringBuilder & sb,const std::string & prefix) const183 void CppServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix) const
184 {
185     AutoPtr<ASTInterfaceType> interface = interface_;
186     while (interface != nullptr) {
187         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
188             EmitServiceImplMethodImpl(method, sb, prefix);
189             sb.Append("\n");
190         }
191         interface = interface->GetExtendsInterface();
192     }
193 }
194 
EmitServiceImplMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const195 void CppServiceImplCodeEmitter::EmitServiceImplMethodImpl(
196     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
197 {
198     if (method->GetParameterNumber() == 0) {
199         sb.Append(prefix).AppendFormat("int32_t %sService::%s()\n", baseName_.c_str(), method->GetName().c_str());
200     } else {
201         StringBuilder paramStr;
202         paramStr.Append(prefix).AppendFormat("int32_t %sService::%s(", baseName_.c_str(), method->GetName().c_str());
203         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
204             AutoPtr<ASTParameter> param = method->GetParameter(i);
205             EmitInterfaceMethodParameter(param, paramStr, "");
206             if (i + 1 < method->GetParameterNumber()) {
207                 paramStr.Append(", ");
208             }
209         }
210 
211         paramStr.AppendFormat(")");
212 
213         sb.Append(SpecificationParam(paramStr, prefix + TAB));
214         sb.Append("\n");
215     }
216 
217     sb.Append(prefix).Append("{\n");
218     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
219     sb.Append(prefix).Append("}\n");
220 }
221 
EmitServiceImplGetMethodImpl(StringBuilder & sb,const std::string & prefix) const222 void CppServiceImplCodeEmitter::EmitServiceImplGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
223 {
224     if (!interface_->IsSerializable()) {
225         sb.Append(prefix).AppendFormat(
226             "extern \"C\" %s *%sImplGetInstance(void)\n", interfaceName_.c_str(), baseName_.c_str());
227         sb.Append(prefix).Append("{\n");
228         sb.Append(prefix + TAB).AppendFormat("return new (std::nothrow) %s();\n", implName_.c_str());
229         sb.Append(prefix).Append("}\n\n");
230     }
231 }
232 } // namespace Idl
233 } // namespace OHOS