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