• 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 "sa_ts_client_proxy_code_emitter.h"
17 #include "util/file.h"
18 #include "util/logger.h"
19 #include "util/string_helper.h"
20 
21 namespace OHOS {
22 namespace Idl {
ResolveDirectory(const std::string & targetDirectory)23 bool SaTsClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
24 {
25     directory_ = GetFileParentPath(targetDirectory);
26     if (!File::CreateParentDir(directory_)) {
27         Logger::E("SaTsClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
28         return false;
29     }
30 
31     return true;
32 }
33 
EmitCode()34 void SaTsClientProxyCodeEmitter::EmitCode()
35 {
36     if (!CheckInterfaceType()) {
37         return;
38     }
39     EmitInterfaceProxyFile();
40 }
41 
EmitInterfaceProxyFile()42 void SaTsClientProxyCodeEmitter::EmitInterfaceProxyFile()
43 {
44     std::string filePath =
45         File::AdapterPath(StringHelper::Format("%s/%s.ts", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
46     File file(filePath, File::WRITE);
47     StringBuilder sb;
48 
49     EmitLicense(sb);
50     EmitInterfaceImports(sb);
51     sb.Append("\n");
52     EmitInterfaceProxyImpl(sb);
53     sb.Append("\n");
54 
55     std::string data = sb.ToString();
56     file.WriteData(data.c_str(), data.size());
57     file.Flush();
58     file.Close();
59 }
60 
EmitInterfaceProxyImpl(StringBuilder & sb)61 void SaTsClientProxyCodeEmitter::EmitInterfaceProxyImpl(StringBuilder &sb)
62 {
63     sb.AppendFormat("export default class %s implements %s {\n", proxyName_.c_str(), interfaceName_.c_str());
64     EmitInterfaceProxyConstructor(sb, TAB);
65     EmitInterfaceProxyMethodImpls(sb, TAB);
66     sb.Append("\n");
67     EmitInterfaceMethodCommands(sb, TAB);
68     sb.Append(TAB).Append("private proxy");
69     sb.Append("\n");
70     sb.Append("}\n");
71 }
72 
EmitInterfaceProxyConstructor(StringBuilder & sb,const std::string & prefix) const73 void SaTsClientProxyCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder &sb, const std::string &prefix) const
74 {
75     sb.Append(prefix).Append("constructor(proxy) {\n");
76     sb.Append(prefix).Append(TAB).Append("this.proxy = proxy;\n");
77     sb.Append(prefix).Append("}\n\n");
78 }
79 
EmitInterfaceProxyMethodImpls(StringBuilder & sb,const std::string & prefix) const80 void SaTsClientProxyCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder &sb, const std::string &prefix) const
81 {
82     int methodNumber = static_cast<int>(interface_->GetMethodNumber());
83     for (int i = 0; i < methodNumber; i++) {
84         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
85         EmitInterfaceMethodHead(method, sb, prefix);
86         sb.Append("): void\n");
87         EmitInterfaceProxyMethodBody(method, sb, prefix);
88         if (i != methodNumber - 1) {
89             sb.Append("\n");
90         }
91     }
92 }
93 
EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const94 void SaTsClientProxyCodeEmitter::EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> &method, StringBuilder &sb,
95     const std::string &prefix) const
96 {
97     bool haveOutPara = false;
98     sb.Append(prefix).Append("{\n");
99     sb.Append(prefix).Append(TAB).Append("let option = new rpc.MessageOption();\n");
100     if (method->IsOneWay() || interface_->IsOneWay()) {
101         sb.Append(prefix).Append(TAB).Append("option.setFlags(_option.TF_ASYNC);\n");
102     }
103     sb.Append(prefix).Append(TAB).Append("let dataSequence = rpc.MessageSequence.create();\n");
104     sb.Append(prefix).Append(TAB).Append("let replySequence = rpc.MessageSequence.create();\n");
105     sb.Append(prefix).Append(TAB).Append("dataSequence.writeInterfaceToken(this.proxy.getDescriptor());\n");
106 
107     int paramNumber = static_cast<int>(method->GetParameterNumber());
108     for (int i = 0; i < paramNumber; i++) {
109         AutoPtr<ASTParameter> param = method->GetParameter(i);
110         if (param->GetAttribute() & ASTParamAttr::PARAM_IN) {
111             AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
112             typeEmitter->EmitTsWriteVar("dataSequence", param->GetName(), sb, prefix + TAB);
113         }
114         if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
115             haveOutPara = true;
116         }
117     }
118     sb.Append(prefix).Append(TAB).AppendFormat(
119         "this.proxy.sendMessageRequest(%s.COMMAND_%s, dataSequence, replySequence, option).", proxyName_.c_str(),
120         ConstantName(method->GetName()).c_str());
121     sb.Append("then((result: rpc.RequestResult) => {\n");
122     EmitInterfaceMethodCallback(method, sb, prefix + TAB + TAB, haveOutPara);
123     sb.Append(prefix).Append(TAB).Append("}).catch((e: Error) => ").Append("{\n");
124     sb.Append(prefix).Append(TAB).Append(TAB).Append(
125         "console.log(\'sendMessageRequest failed, message: \' + e.message);\n");
126     sb.Append(prefix).Append(TAB).Append("}).finally(() => ").Append("{\n");
127     sb.Append(prefix).Append(TAB).Append(TAB).Append("dataSequence.reclaim();").Append("\n");
128     sb.Append(prefix).Append(TAB).Append(TAB).Append("replySequence.reclaim();").Append("\n");
129     sb.Append(prefix).Append(TAB).Append("});").Append("\n");
130     sb.Append(prefix).Append("}\n");
131 }
132 
EmitInterfaceMethodCallback(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix,bool haveOutPara) const133 void SaTsClientProxyCodeEmitter::EmitInterfaceMethodCallback(AutoPtr<ASTMethod> &method, StringBuilder &sb,
134     const std::string &prefix, bool haveOutPara) const
135 {
136     sb.Append(prefix).Append("if (result.errCode === 0) {\n");
137     // emit errCode
138     AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(new ASTIntegerType());
139     if (typeEmitter == nullptr) {
140         return;
141     }
142     typeEmitter->EmitTsReadVar("result.reply", SuffixAdded(ERR_CODE).c_str(), sb, prefix + TAB);
143     EmitInterfaceMethodErrorCallback(method, sb, prefix + TAB, haveOutPara);
144     EmitInterfaceMethodCallbackInner(method, sb, prefix);
145 }
146 
EmitInterfaceMethodErrorCallback(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix,bool haveOutPara) const147 void SaTsClientProxyCodeEmitter::EmitInterfaceMethodErrorCallback(AutoPtr<ASTMethod> &method, StringBuilder &sb,
148     const std::string &prefix, bool haveOutPara) const
149 {
150     TypeKind retKind = method->GetReturnType()->GetTypeKind();
151     if ((retKind != TypeKind::TYPE_VOID) || haveOutPara) {
152         sb.Append(prefix).AppendFormat("if (%s != 0) {\n", SuffixAdded(ERR_CODE).c_str());
153         int paramNumber = static_cast<int>(method->GetParameterNumber());
154         for (int i = 0; i < paramNumber; i++) {
155             AutoPtr<ASTParameter> param = method->GetParameter(i);
156             if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
157                 sb.Append(prefix).Append(TAB).AppendFormat("let %s = undefined;\n",
158                     SuffixAdded(param->GetName()).c_str());
159             }
160         }
161         if (retKind != TypeKind::TYPE_VOID) {
162             sb.Append(prefix).Append(TAB).AppendFormat(
163                 "let %s = undefined;\n", SuffixAdded(RETURN_VALUE).c_str());
164         }
165         sb.Append(prefix).Append(TAB).AppendFormat("callback(%s", SuffixAdded(ERR_CODE).c_str());
166         if (retKind != TypeKind::TYPE_VOID) {
167             sb.AppendFormat(", %s", SuffixAdded(RETURN_VALUE).c_str());
168         }
169         for (int i = 0; i < paramNumber; i++) {
170             AutoPtr<ASTParameter> param = method->GetParameter(i);
171             if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
172                 sb.AppendFormat(", %s", SuffixAdded(param->GetName()).c_str());
173             }
174         }
175         sb.Append(");\n");
176         sb.Append(prefix).Append(TAB).Append("return;\n");
177         sb.Append(prefix).Append("}\n");
178     }
179 }
180 
EmitInterfaceMethodCallbackInner(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const181 void SaTsClientProxyCodeEmitter::EmitInterfaceMethodCallbackInner(AutoPtr<ASTMethod> &method, StringBuilder &sb,
182     const std::string &prefix) const
183 {
184     // emit return
185     int paramNumber = static_cast<int>(method->GetParameterNumber());
186     for (int i = 0; i < paramNumber; i++) {
187         AutoPtr<ASTParameter> param = method->GetParameter(i);
188         if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
189             AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
190             if (typeEmitter == nullptr) {
191                 return;
192             }
193             typeEmitter->EmitTsReadVar("result.reply", SuffixAdded(param->GetName()), sb, prefix + TAB,
194                 TypeMode::PARAM_OUT);
195         }
196     }
197     AutoPtr<ASTType> returnType = method->GetReturnType();
198     if (returnType->GetTypeKind() != TypeKind::TYPE_VOID) {
199         AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(returnType);
200         if (typeEmitter != nullptr) {
201             typeEmitter->EmitTsReadVar("result.reply",
202                 SuffixAdded(RETURN_VALUE), sb, prefix + TAB, TypeMode::PARAM_OUT);
203         }
204     }
205     sb.Append(prefix + TAB).AppendFormat("callback(%s", SuffixAdded(ERR_CODE).c_str());
206     if (returnType->GetTypeKind() != TypeKind::TYPE_VOID) {
207         sb.AppendFormat(", %s", SuffixAdded(RETURN_VALUE).c_str());
208     }
209     for (int i = 0; i < paramNumber; i++) {
210         AutoPtr<ASTParameter> param = method->GetParameter(i);
211         if (param->GetAttribute() & ASTParamAttr::PARAM_OUT) {
212             sb.AppendFormat(", %s", SuffixAdded(param->GetName()).c_str());
213         }
214     }
215     sb.Append(");\n");
216     sb.Append(prefix).Append("} else {\n");
217     sb.Append(prefix).Append(TAB).Append("console.log(\"sendMessageRequest failed, errCode: \" + result.errCode);\n");
218     sb.Append(prefix).Append("}\n");
219 }
220 } // namespace Idl
221 } // namespace OHOS