• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "ast/ast_interface_type.h"
10 #include "util/string_builder.h"
11 
12 namespace OHOS {
13 namespace HDI {
SetNamespace(const AutoPtr<ASTNamespace> & nspace)14 void ASTInterfaceType::SetNamespace(const AutoPtr<ASTNamespace> &nspace)
15 {
16     ASTType::SetNamespace(nspace);
17     if (namespace_ != nullptr) {
18         namespace_->AddInterface(this);
19     }
20 }
21 
AddMethod(const AutoPtr<ASTMethod> & method)22 void ASTInterfaceType::AddMethod(const AutoPtr<ASTMethod> &method)
23 {
24     if (method == nullptr) {
25         return;
26     }
27     methods_.push_back(method);
28 }
29 
GetMethod(size_t index)30 AutoPtr<ASTMethod> ASTInterfaceType::GetMethod(size_t index)
31 {
32     if (index >= methods_.size()) {
33         return nullptr;
34     }
35 
36     return methods_[index];
37 }
38 
IsInterfaceType()39 bool ASTInterfaceType::IsInterfaceType()
40 {
41     return true;
42 }
43 
ToString() const44 std::string ASTInterfaceType::ToString() const
45 {
46     return name_;
47 }
48 
Dump(const std::string & prefix)49 std::string ASTInterfaceType::Dump(const std::string &prefix)
50 {
51     StringBuilder sb;
52 
53     sb.Append(prefix);
54     sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
55     sb.AppendFormat("interface %s {\n", name_.c_str());
56     for (auto method : methods_) {
57         std::string info = method->Dump(prefix + "  ");
58         sb.Append(info);
59         if (method != methods_[methods_.size() - 1]) {
60             sb.Append('\n');
61         }
62     }
63     sb.Append(prefix).Append("}\n");
64 
65     return sb.ToString();
66 }
67 
GetTypeKind()68 TypeKind ASTInterfaceType::GetTypeKind()
69 {
70     return TypeKind::TYPE_INTERFACE;
71 }
72 
GetFullName() const73 std::string ASTInterfaceType::GetFullName() const
74 {
75     return namespace_->ToString() + name_;
76 }
77 
EmitDescMacroName() const78 std::string ASTInterfaceType::EmitDescMacroName() const
79 {
80     return StringHelper::Format("%s_INTERFACE_DESC", StringHelper::StrToUpper(name_).c_str());
81 }
82 
EmitCType(TypeMode mode) const83 std::string ASTInterfaceType::EmitCType(TypeMode mode) const
84 {
85     switch (mode) {
86         case TypeMode::NO_MODE:
87             return StringHelper::Format("struct %s", name_.c_str());
88         case TypeMode::PARAM_IN:
89             return StringHelper::Format("struct %s*", name_.c_str());
90         case TypeMode::PARAM_OUT:
91             return StringHelper::Format("struct %s**", name_.c_str());
92         case TypeMode::LOCAL_VAR:
93             return StringHelper::Format("struct %s*", name_.c_str());
94         default:
95             return "unknow type";
96     }
97 }
98 
EmitCppType(TypeMode mode) const99 std::string ASTInterfaceType::EmitCppType(TypeMode mode) const
100 {
101     switch (mode) {
102         case TypeMode::NO_MODE:
103             return StringHelper::Format("sptr<%s>", name_.c_str());
104         case TypeMode::PARAM_IN:
105             return StringHelper::Format("const sptr<%s>&", name_.c_str());
106         case TypeMode::PARAM_OUT:
107             return StringHelper::Format("sptr<%s>&", name_.c_str());
108         case TypeMode::LOCAL_VAR:
109             return StringHelper::Format("sptr<%s>", name_.c_str());
110         default:
111             return "unknow type";
112     }
113 }
114 
EmitJavaType(TypeMode mode,bool isInnerType) const115 std::string ASTInterfaceType::EmitJavaType(TypeMode mode, bool isInnerType) const
116 {
117     return name_;
118 }
119 
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const120 void ASTInterfaceType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
121     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
122 {
123     sb.Append(prefix).AppendFormat("if (!WriteInterface(%s, %s, %s)) {\n", parcelName.c_str(),
124         EmitDescMacroName().c_str(), name.c_str());
125     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
126     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
127     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
128     sb.Append(prefix).Append("}\n");
129 }
130 
EmitCProxyReadVar(const std::string & parcelName,const std::string & name,bool isInnerType,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const131 void ASTInterfaceType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
132     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
133 {
134     sb.Append(prefix).AppendFormat("*%s = Read%s(%s);\n", name.c_str(), name_.c_str(), parcelName.c_str());
135     sb.Append(prefix).AppendFormat("if (*%s == NULL) {\n", name.c_str());
136     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
137     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
138     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
139     sb.Append(prefix).Append("}\n");
140 }
141 
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const142 void ASTInterfaceType::EmitCStubReadVar(const std::string &parcelName, const std::string &name,
143     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
144 {
145     sb.Append(prefix).AppendFormat("%s = Read%s(%s);\n", name.c_str(), name_.c_str(), parcelName.c_str());
146     sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
147     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
148     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
149     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
150     sb.Append(prefix).Append("}\n");
151 }
152 
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const153 void ASTInterfaceType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
154     const std::string &prefix, unsigned int innerLevel) const
155 {
156     sb.Append(prefix).AppendFormat("if (!%s.WriteRemoteObject(", parcelName.c_str());
157     sb.AppendFormat("OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(%s, %s::GetDescriptor()))) {\n",
158         name.c_str(), name_.c_str());
159     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
160     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
161     sb.Append(prefix).Append("}\n");
162 }
163 
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const164 void ASTInterfaceType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
165     const std::string &prefix, bool initVariable, unsigned int innerLevel) const
166 {
167     if (initVariable) {
168         sb.Append(prefix).AppendFormat("sptr<%s> %s;\n", name_.c_str(), name.c_str());
169     }
170     sb.Append(prefix).AppendFormat(
171         "if (!ReadInterface<%s>(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str());
172     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read interface object\", __func__);\n");
173     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
174     sb.Append(prefix).Append("}\n");
175 }
176 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const177 void ASTInterfaceType::EmitJavaWriteVar(
178     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
179 {
180     sb.Append(prefix).AppendFormat("%s.writeRemoteObject(%s.asObject());\n", parcelName.c_str(), name.c_str());
181 }
182 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const183 void ASTInterfaceType::EmitJavaReadVar(
184     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
185 {
186     std::string stubName = StringHelper::StartWith(name_, "I") ? (name_.substr(1) + "Stub") : (name_ + "Stub");
187     sb.Append(prefix).AppendFormat(
188         "%s = %s.asInterface(%s.readRemoteObject());\n", name.c_str(), stubName.c_str(), parcelName.c_str());
189 }
190 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const191 void ASTInterfaceType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
192     StringBuilder &sb, const std::string &prefix) const
193 {
194     std::string stubName = StringHelper::StartWith(name_, "I") ? (name_.substr(1) + "Stub") : (name_ + "Stub");
195     sb.Append(prefix).AppendFormat("%s %s = %s.asInterface(%s.readRemoteObject());\n",
196         EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), stubName.c_str(), parcelName.c_str());
197 }
198 
RegisterWriteMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const199 void ASTInterfaceType::RegisterWriteMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
200 {
201     using namespace std::placeholders;
202     std::string methodName = "WriteInterface";
203     switch (language) {
204         case Options::Language::C:
205             methods.emplace(methodName, std::bind(&ASTInterfaceType::EmitCWriteMethods, this, _1, _2, _3, _4));
206             break;
207         default:
208             break;
209     }
210 }
211 
RegisterReadMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const212 void ASTInterfaceType::RegisterReadMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
213 {
214     using namespace std::placeholders;
215 
216     switch (language) {
217         case Options::Language::C: {
218             std::string methodName = StringHelper::Format("Read%s", name_.c_str());
219             methods.emplace(methodName, std::bind(&ASTInterfaceType::EmitCReadMethods, this, _1, _2, _3, _4));
220             break;
221         }
222         case Options::Language::CPP: {
223             methods.emplace("ReadInterface", std::bind(&ASTInterfaceType::EmitCppReadMethods, this, _1, _2, _3, _4));
224             break;
225         }
226         default:
227             break;
228     }
229 }
230 
EmitCWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const231 void ASTInterfaceType::EmitCWriteMethods(StringBuilder &sb, const std::string &prefix,
232     const std::string &methodPrefix, bool isDecl) const
233 {
234     std::string methodName = StringHelper::Format("%sWriteInterface", methodPrefix.c_str());
235     if (isDecl) {
236         sb.Append(prefix).AppendFormat("static bool %s(struct HdfSBuf *parcel, const char *desc, void *interface);\n",
237             methodName.c_str());
238         return;
239     }
240     sb.Append(prefix).AppendFormat("static bool %s(struct HdfSBuf *parcel, const char *desc, void *interface)\n",
241         methodName.c_str());
242     sb.Append(prefix).Append("{\n");
243     sb.Append(prefix + TAB).Append("if (interface == NULL) {\n");
244     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid interface object\", __func__);\n");
245     sb.Append(prefix + TAB + TAB).Append("return false;\n");
246     sb.Append(prefix + TAB).Append("}\n\n");
247     sb.Append(prefix + TAB).Append("struct HdfRemoteService **stub = StubCollectorGetOrNewObject(desc, interface);\n");
248     sb.Append(prefix + TAB).Append("if (stub == NULL) {\n");
249     sb.Append(prefix + TAB + TAB).Append(
250         "HDF_LOGE(\"%{public}s: failed to get stub of '%{public}s'\", __func__, desc);\n");
251     sb.Append(prefix + TAB + TAB).Append("return false;\n");
252     sb.Append(prefix + TAB).Append("}\n\n");
253     sb.Append(prefix + TAB).Append("if (HdfSbufWriteRemoteService(parcel, *stub) != HDF_SUCCESS) {\n");
254     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write remote service\", __func__);\n");
255     sb.Append(prefix + TAB + TAB).Append("return false;\n");
256     sb.Append(prefix + TAB).Append("}\n\n");
257     sb.Append(prefix + TAB).Append("return true;\n");
258     sb.Append(prefix).Append("}\n");
259 }
260 
EmitCReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const261 void ASTInterfaceType::EmitCReadMethods(StringBuilder &sb, const std::string &prefix,
262     const std::string &methodPrefix, bool isDecl) const
263 {
264     std::string methodName = StringHelper::Format("%sRead%s", methodPrefix.c_str(), name_.c_str());
265     if (isDecl) {
266         sb.Append(prefix).AppendFormat("static struct %s *%s(struct HdfSBuf *parcel);\n", name_.c_str(),
267             methodName.c_str());
268         return;
269     }
270     sb.Append(prefix).AppendFormat("static struct %s *%s(struct HdfSBuf *parcel)\n", name_.c_str(),
271         methodName.c_str());
272     sb.Append(prefix).Append("{\n");
273     sb.Append(prefix + TAB).Append("struct HdfRemoteService *remote = HdfSbufReadRemoteService(parcel);\n");
274     sb.Append(prefix + TAB).Append("if (remote == NULL) {\n");
275     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: ");
276     sb.AppendFormat(" failed to read remote service of '%s'\", __func__);\n", name_.c_str());
277     sb.Append(prefix + TAB + TAB).Append("return NULL;\n");
278     sb.Append(prefix + TAB).Append("}\n\n");
279     sb.Append(prefix + TAB).AppendFormat("return %sGet(remote);\n", name_.c_str());
280     sb.Append(prefix).Append("}\n");
281 }
282 
EmitCppReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const283 void ASTInterfaceType::EmitCppReadMethods(StringBuilder &sb, const std::string &prefix,
284     const std::string &methodPrefix, bool isDecl) const
285 {
286     std::string methodName = StringHelper::Format("%sReadInterface", methodPrefix.c_str(), name_.c_str());
287     sb.Append(prefix).AppendFormat("template<typename InterfaceType>\n");
288     sb.Append(prefix).AppendFormat("static bool %s(MessageParcel &parcel, sptr<InterfaceType>& object)",
289         methodName.c_str());
290     if (isDecl) {
291         sb.Append(";\n");
292         return;
293     } else {
294         sb.Append("\n");
295     }
296 
297     sb.Append(prefix).Append("{\n");
298     sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = parcel.ReadRemoteObject();\n");
299     sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
300     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: read an invalid remote object\", __func__);\n");
301     sb.Append(prefix + TAB + TAB).Append("return false;\n");
302     sb.Append(prefix + TAB).Append("}\n\n");
303     sb.Append(prefix + TAB).Append("object = hdi_facecast<InterfaceType>(remote);\n");
304     sb.Append(prefix + TAB).Append("if (object == nullptr) {\n");
305     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to cast interface object\", __func__);\n");
306     sb.Append(prefix + TAB + TAB).Append("return false;\n");
307     sb.Append(prefix + TAB).Append("}\n");
308     sb.Append(prefix + TAB).Append("return true;\n");
309     sb.Append(prefix).Append("}\n");
310 }
311 } // namespace HDI
312 } // namespace OHOS