• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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/java_client_proxy_code_emitter.h"
10 #include "util/logger.h"
11 
12 namespace OHOS {
13 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)14 bool JavaClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
15 {
16     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
17         directory_ = GetFileParentPath(targetDirectory);
18     } else {
19         return false;
20     }
21 
22     if (!File::CreateParentDir(directory_)) {
23         Logger::E("CppClientInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
24         return false;
25     }
26 
27     return true;
28 }
29 
EmitCode()30 void JavaClientProxyCodeEmitter::EmitCode()
31 {
32     if (mode_ == GenMode::IPC) {
33         EmitProxyFile();
34     }
35 }
36 
EmitProxyFile()37 void JavaClientProxyCodeEmitter::EmitProxyFile()
38 {
39     std::string filePath =
40         File::AdapterPath(StringHelper::Format("%s/%s.java", directory_.c_str(), FileName(proxyName_).c_str()));
41     File file(filePath, File::WRITE);
42     StringBuilder sb;
43 
44     EmitLicense(sb);
45     EmitPackage(sb);
46     sb.Append("\n");
47     EmitProxyImports(sb);
48     sb.Append("\n");
49     EmitProxyImpl(sb);
50 
51     std::string data = sb.ToString();
52     file.WriteData(data.c_str(), data.size());
53     file.Flush();
54     file.Close();
55 }
56 
EmitProxyImports(StringBuilder & sb) const57 void JavaClientProxyCodeEmitter::EmitProxyImports(StringBuilder &sb) const
58 {
59     EmitProxyCorelibImports(sb);
60     EmitProxySelfDefinedTypeImports(sb);
61     EmitProxyDBinderImports(sb);
62 }
63 
EmitProxyCorelibImports(StringBuilder & sb) const64 void JavaClientProxyCodeEmitter::EmitProxyCorelibImports(StringBuilder &sb) const
65 {
66     bool includeList = false;
67     bool includeMap = false;
68     const AST::TypeStringMap &types = ast_->GetTypes();
69     for (const auto &pair : types) {
70         AutoPtr<ASTType> type = pair.second;
71         switch (type->GetTypeKind()) {
72             case TypeKind::TYPE_LIST: {
73                 if (!includeList) {
74                     sb.Append("import java.util.List;\n");
75                     includeList = true;
76                 }
77                 break;
78             }
79             case TypeKind::TYPE_MAP: {
80                 if (!includeMap) {
81                     sb.Append("import java.util.Map;\n");
82                     sb.Append("import java.util.HashMap;\n");
83                     includeMap = true;
84                 }
85                 break;
86             }
87             default:
88                 break;
89         }
90     }
91 }
92 
EmitProxySelfDefinedTypeImports(StringBuilder & sb) const93 void JavaClientProxyCodeEmitter::EmitProxySelfDefinedTypeImports(StringBuilder &sb) const
94 {
95     for (const auto &importPair : ast_->GetImports()) {
96         AutoPtr<AST> import = importPair.second;
97         sb.AppendFormat("import %s;\n", import->GetFullName().c_str());
98     }
99 }
100 
EmitProxyDBinderImports(StringBuilder & sb) const101 void JavaClientProxyCodeEmitter::EmitProxyDBinderImports(StringBuilder &sb) const
102 {
103     sb.Append("import ohos.hiviewdfx.HiLog;\n");
104     sb.Append("import ohos.hiviewdfx.HiLogLabel;\n");
105     sb.Append("import ohos.rpc.IRemoteObject;\n");
106     sb.Append("import ohos.rpc.RemoteException;\n");
107     sb.Append("import ohos.rpc.MessageParcel;\n");
108     sb.Append("import ohos.rpc.MessageOption;\n");
109 }
110 
EmitProxyImpl(StringBuilder & sb)111 void JavaClientProxyCodeEmitter::EmitProxyImpl(StringBuilder &sb)
112 {
113     sb.AppendFormat("public class %s implements %s {\n", proxyName_.c_str(), interfaceName_.c_str());
114     EmitProxyConstants(sb, TAB);
115     sb.Append("\n");
116     sb.Append(TAB).AppendFormat(
117         "private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_CORE, 0xD002510, \"%s\");\n",
118         interfaceFullName_.c_str());
119     sb.Append(TAB).Append("private final IRemoteObject remote;\n");
120     sb.Append(TAB).Append("private static final int ERR_OK = 0;\n");
121     sb.Append("\n");
122     EmitProxyConstructor(sb, TAB);
123     sb.Append("\n");
124     EmitProxyMethodImpls(sb, TAB);
125     sb.Append("};");
126 }
127 
EmitProxyConstants(StringBuilder & sb,const std::string & prefix)128 void JavaClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix)
129 {
130     sb.Append(prefix).AppendFormat(
131         "private static final std::string DESCRIPTOR = \"%s\";\n\n", interfaceFullName_.c_str());
132     EmitInterfaceMethodCommands(sb, prefix);
133 }
134 
EmitProxyConstructor(StringBuilder & sb,const std::string & prefix) const135 void JavaClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
136 {
137     sb.Append(prefix).AppendFormat("public %s(IRemoteObject remote) {\n", proxyName_.c_str());
138     sb.Append(prefix + TAB).Append("this.remote = remote;\n");
139     sb.Append(prefix).Append("}\n");
140     sb.Append("\n");
141     sb.Append(prefix).AppendFormat("@Override\n");
142     sb.Append(prefix).Append("public IRemoteObject asObject() {\n");
143     sb.Append(prefix + TAB).Append("return remote;\n");
144     sb.Append(prefix).Append("}\n");
145 }
146 
EmitProxyMethodImpls(StringBuilder & sb,const std::string & prefix) const147 void JavaClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix) const
148 {
149     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
150         EmitProxyMethodImpl(method, sb, prefix);
151         sb.Append("\n");
152     }
153 }
154 
EmitProxyMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const155 void JavaClientProxyCodeEmitter::EmitProxyMethodImpl(
156     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
157 {
158     sb.Append(prefix).Append("@Override\n");
159     if (method->GetParameterNumber() == 0) {
160         sb.Append(prefix).AppendFormat(
161             "public int %s() throws RemoteException ", MethodName(method->GetName()).c_str());
162     } else {
163         StringBuilder paramStr;
164         paramStr.Append(prefix).AppendFormat("public int %s(", MethodName(method->GetName()).c_str());
165         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
166             AutoPtr<ASTParameter> param = method->GetParameter(i);
167             EmitInterfaceMethodParameter(param, paramStr, "");
168             if (i + 1 < method->GetParameterNumber()) {
169                 paramStr.Append(", ");
170             }
171         }
172         paramStr.Append(") throws RemoteException");
173 
174         sb.Append(SpecificationParam(paramStr, prefix + TAB));
175         sb.Append("\n");
176     }
177     EmitProxyMethodBody(method, sb, prefix);
178 }
179 
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const180 void JavaClientProxyCodeEmitter::EmitInterfaceMethodParameter(
181     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix) const
182 {
183     sb.Append(prefix).Append(param->EmitJavaParameter());
184 }
185 
EmitProxyMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const186 void JavaClientProxyCodeEmitter::EmitProxyMethodBody(
187     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
188 {
189     sb.Append(prefix).Append("{\n");
190     sb.Append(prefix + TAB).Append("MessageParcel data = MessageParcel.obtain();\n");
191     sb.Append(prefix + TAB).Append("MessageParcel reply = MessageParcel.obtain();\n");
192     sb.Append(prefix + TAB).AppendFormat("MessageOption option = new MessageOption(MessageOption.TF_SYNC);\n");
193     sb.Append("\n");
194     sb.Append(prefix).AppendFormat("    data.writeInterfaceToken(DESCRIPTOR);\n");
195 
196     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
197         AutoPtr<ASTParameter> param = method->GetParameter(i);
198         param->EmitJavaWriteVar("data", sb, prefix + TAB);
199     }
200     sb.Append("\n");
201 
202     sb.Append(prefix + TAB).Append("try {\n");
203     sb.Append(prefix + TAB + TAB).AppendFormat("if (remote.sendRequest(COMMAND_%s, data, reply, option)) {\n",
204         ConstantName(method->GetName()).c_str());
205     sb.Append(prefix + TAB + TAB + TAB).Append("return 1;\n");
206     sb.Append(prefix + TAB + TAB).Append("}\n");
207     sb.Append(prefix + TAB).Append("    reply.readException();\n");
208     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
209         AutoPtr<ASTParameter> param = method->GetParameter(i);
210         param->EmitJavaReadVar("reply", sb, prefix + TAB + TAB);
211     }
212 
213     sb.Append(prefix + TAB).Append("} finally {\n");
214     sb.Append(prefix + TAB + TAB).Append("data.reclaim();\n");
215     sb.Append(prefix + TAB + TAB).Append("reply.reclaim();\n");
216     sb.Append(prefix + TAB).Append("}\n");
217     sb.Append(prefix + TAB).Append("return 0;\n");
218     sb.Append(prefix).Append("}\n");
219 }
220 
EmitLocalVariable(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const221 void JavaClientProxyCodeEmitter::EmitLocalVariable(
222     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix) const
223 {
224     AutoPtr<ASTType> type = param->GetType();
225     if (type->GetTypeKind() == TypeKind::TYPE_SEQUENCEABLE) {
226         sb.Append(prefix).AppendFormat("%s %s = new %s();\n", type->EmitJavaType(TypeMode::NO_MODE).c_str(),
227             param->GetName().c_str(), type->EmitJavaType(TypeMode::NO_MODE).c_str());
228     } else if (type->GetTypeKind() == TypeKind::TYPE_LIST) {
229         sb.Append(prefix).AppendFormat("%s %s = new Array%s();\n", type->EmitJavaType(TypeMode::NO_MODE).c_str(),
230             param->GetName().c_str(), type->EmitJavaType(TypeMode::NO_MODE).c_str());
231     } else if (type->GetTypeKind() == TypeKind::TYPE_MAP) {
232         sb.Append(prefix).AppendFormat("%s %s = new Hash%s();\n", type->EmitJavaType(TypeMode::NO_MODE).c_str(),
233             param->GetName().c_str(), type->EmitJavaType(TypeMode::NO_MODE).c_str());
234     } else {
235         sb.Append(prefix).AppendFormat(
236             "%s %s;\n", type->EmitJavaType(TypeMode::NO_MODE).c_str(), param->GetName().c_str());
237     }
238 }
239 } // namespace HDI
240 } // namespace OHOS