• 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 "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 
AddExtendsInterface(AutoPtr<ASTInterfaceType> interface)39 bool ASTInterfaceType::AddExtendsInterface(AutoPtr<ASTInterfaceType> interface)
40 {
41     if (extendsInterface_ != nullptr) {
42         return false;
43     }
44     extendsInterface_ = interface;
45     return true;
46 }
47 
SetVersion(size_t & majorVer,size_t & minorVer)48 void ASTInterfaceType::SetVersion(size_t &majorVer, size_t &minorVer)
49 {
50     majorVersion_ = majorVer;
51     minorVersion_ = minorVer;
52 }
53 
GetMethodsBySystem(SystemLevel system) const54 std::vector<AutoPtr<ASTMethod>> ASTInterfaceType::GetMethodsBySystem(SystemLevel system) const
55 {
56     std::vector<AutoPtr<ASTMethod>> methods;
57     for (const auto &method : methods_) {
58         if (method->GetAttribute()->Match(system)) {
59             methods.push_back(method);
60         }
61     }
62     return methods;
63 }
64 
IsInterfaceType()65 bool ASTInterfaceType::IsInterfaceType()
66 {
67     return true;
68 }
69 
Dump(const std::string & prefix)70 std::string ASTInterfaceType::Dump(const std::string &prefix)
71 {
72     StringBuilder sb;
73 
74     sb.Append(prefix);
75     sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
76     sb.AppendFormat("interface %s {\n", name_.c_str());
77     for (auto method : methods_) {
78         std::string info = method->Dump(prefix + "  ");
79         sb.Append(info);
80         if (method != methods_[methods_.size() - 1]) {
81             sb.Append('\n');
82         }
83     }
84     sb.Append(prefix).Append("}\n");
85 
86     return sb.ToString();
87 }
88 
GetTypeKind()89 TypeKind ASTInterfaceType::GetTypeKind()
90 {
91     return TypeKind::TYPE_INTERFACE;
92 }
93 
GetFullName() const94 std::string ASTInterfaceType::GetFullName() const
95 {
96     return namespace_->ToString() + name_;
97 }
98 
EmitDescMacroName() const99 std::string ASTInterfaceType::EmitDescMacroName() const
100 {
101     return StringHelper::Format("%s_INTERFACE_DESC", StringHelper::StrToUpper(name_).c_str());
102 }
103 
EmitCType(TypeMode mode) const104 std::string ASTInterfaceType::EmitCType(TypeMode mode) const
105 {
106     switch (mode) {
107         case TypeMode::NO_MODE:
108             return StringHelper::Format("struct %s", name_.c_str());
109         case TypeMode::PARAM_IN:
110             return StringHelper::Format("struct %s*", name_.c_str());
111         case TypeMode::PARAM_OUT:
112             return StringHelper::Format("struct %s**", name_.c_str());
113         case TypeMode::LOCAL_VAR:
114             return StringHelper::Format("struct %s*", name_.c_str());
115         default:
116             return "unknow type";
117     }
118 }
119 
EmitCppType(TypeMode mode) const120 std::string ASTInterfaceType::EmitCppType(TypeMode mode) const
121 {
122     std::string pointerName = "sptr";
123     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
124         pointerName = "std::shared_ptr";
125     }
126     switch (mode) {
127         case TypeMode::NO_MODE:
128             return StringHelper::Format("%s<%s>", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
129         case TypeMode::PARAM_IN:
130             return StringHelper::Format(
131                 "const %s<%s>&", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
132         case TypeMode::PARAM_OUT:
133             return StringHelper::Format(
134                 "%s<%s>&", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
135         case TypeMode::LOCAL_VAR:
136             return StringHelper::Format("%s<%s>", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
137         default:
138             return "unknow type";
139     }
140 }
141 
EmitJavaType(TypeMode mode,bool isInnerType) const142 std::string ASTInterfaceType::EmitJavaType(TypeMode mode, bool isInnerType) const
143 {
144     return name_;
145 }
146 
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const147 void ASTInterfaceType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
148     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
149 {
150     sb.Append(prefix).AppendFormat("if (!WriteInterface(%s, %s, %s)) {\n", parcelName.c_str(),
151         EmitDescMacroName().c_str(), name.c_str());
152     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
153     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
154     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
155     sb.Append(prefix).Append("}\n");
156 }
157 
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) const158 void ASTInterfaceType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
159     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
160 {
161     sb.Append(prefix).AppendFormat("*%s = Read%s(%s);\n", name.c_str(), name_.c_str(), parcelName.c_str());
162     sb.Append(prefix).AppendFormat("if (*%s == NULL) {\n", name.c_str());
163     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
164     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
165     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
166     sb.Append(prefix).Append("}\n");
167 }
168 
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const169 void ASTInterfaceType::EmitCStubReadVar(const std::string &parcelName, const std::string &name,
170     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
171 {
172     sb.Append(prefix).AppendFormat("%s = Read%s(%s);\n", name.c_str(), name_.c_str(), parcelName.c_str());
173     sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
174     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
175     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
176     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
177     sb.Append(prefix).Append("}\n");
178 }
179 
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const180 void ASTInterfaceType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
181     const std::string &prefix, unsigned int innerLevel) const
182 {
183     sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
184     sb.Append(prefix + TAB)
185         .AppendFormat("HDF_LOGE(\"%%{public}s: parameter %s is nullptr!\", __func__);\n", name.c_str());
186     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
187     sb.Append(prefix).Append("}\n");
188     sb.Append("\n");
189     sb.Append(prefix).AppendFormat("if (!%s.WriteRemoteObject(", parcelName.c_str());
190     sb.AppendFormat("OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(%s, %s::GetDescriptor()))) {\n",
191         name.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
192     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
193     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
194     sb.Append(prefix).Append("}\n");
195 }
196 
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const197 void ASTInterfaceType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
198     const std::string &prefix, bool initVariable, unsigned int innerLevel) const
199 {
200     if (initVariable) {
201         sb.Append(prefix).AppendFormat("sptr<%s> %s;\n", GetNameWithNamespace(namespace_, name_).c_str(), name.c_str());
202     }
203     sb.Append(prefix).AppendFormat("sptr<IRemoteObject> %sRemote = %s.ReadRemoteObject();\n", name.c_str(),
204         parcelName.c_str());
205     sb.Append(prefix).AppendFormat("if (%sRemote == nullptr) {\n", name.c_str());
206     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: read an invalid remote object\", __func__);\n");
207     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
208     sb.Append(prefix).Append("}\n\n");
209     sb.Append(prefix).AppendFormat("%s = new %s(%sRemote);\n", name.c_str(),
210         ((StringHelper::StartWith(name_, "I") ? name_.substr(1) : name_) + "Proxy").c_str(), name.c_str());
211     sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
212     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to create interface object\", __func__);\n");
213     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
214     sb.Append(prefix).Append("}\n");
215 }
216 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const217 void ASTInterfaceType::EmitJavaWriteVar(
218     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
219 {
220     sb.Append(prefix).AppendFormat("%s.writeRemoteObject(%s.asObject());\n", parcelName.c_str(), name.c_str());
221 }
222 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const223 void ASTInterfaceType::EmitJavaReadVar(
224     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
225 {
226     std::string stubName = StringHelper::StartWith(name_, "I") ? (name_.substr(1) + "Stub") : (name_ + "Stub");
227     sb.Append(prefix).AppendFormat(
228         "%s = %s.asInterface(%s.readRemoteObject());\n", name.c_str(), stubName.c_str(), parcelName.c_str());
229 }
230 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const231 void ASTInterfaceType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
232     StringBuilder &sb, const std::string &prefix) const
233 {
234     std::string stubName = StringHelper::StartWith(name_, "I") ? (name_.substr(1) + "Stub") : (name_ + "Stub");
235     sb.Append(prefix).AppendFormat("%s %s = %s.asInterface(%s.readRemoteObject());\n",
236         EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), stubName.c_str(), parcelName.c_str());
237 }
238 
RegisterWriteMethod(Language language,SerMode mode,UtilMethodMap & methods) const239 void ASTInterfaceType::RegisterWriteMethod(Language language, SerMode mode, UtilMethodMap &methods) const
240 {
241     using namespace std::placeholders;
242     if (language == Language::C) {
243         methods.emplace("WriteInterface", std::bind(&ASTInterfaceType::EmitCWriteMethods, this, _1, _2, _3, _4));
244     }
245 }
246 
RegisterReadMethod(Language language,SerMode mode,UtilMethodMap & methods) const247 void ASTInterfaceType::RegisterReadMethod(Language language, SerMode mode, UtilMethodMap &methods) const
248 {
249     using namespace std::placeholders;
250 
251     switch (language) {
252         case Language::C: {
253             std::string methodName = StringHelper::Format("Read%s", name_.c_str());
254             methods.emplace(methodName, std::bind(&ASTInterfaceType::EmitCReadMethods, this, _1, _2, _3, _4));
255             break;
256         }
257         default:
258             break;
259     }
260 }
261 
EmitCWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const262 void ASTInterfaceType::EmitCWriteMethods(StringBuilder &sb, const std::string &prefix,
263     const std::string &methodPrefix, bool isDecl) const
264 {
265     std::string methodName = StringHelper::Format("%sWriteInterface", methodPrefix.c_str());
266     if (isDecl) {
267         sb.Append(prefix).AppendFormat("static bool %s(struct HdfSBuf *parcel, const char *desc, void *interface);\n",
268             methodName.c_str());
269         return;
270     }
271     sb.Append(prefix).AppendFormat("static bool %s(struct HdfSBuf *parcel, const char *desc, void *interface)\n",
272         methodName.c_str());
273     sb.Append(prefix).Append("{\n");
274     sb.Append(prefix + TAB).Append("if (interface == NULL) {\n");
275     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid interface object\", __func__);\n");
276     sb.Append(prefix + TAB + TAB).Append("return false;\n");
277     sb.Append(prefix + TAB).Append("}\n\n");
278     sb.Append(prefix + TAB).Append("struct HdfRemoteService **stub = StubCollectorGetOrNewObject(desc, interface);\n");
279     sb.Append(prefix + TAB).Append("if (stub == NULL) {\n");
280     sb.Append(prefix + TAB + TAB).Append(
281         "HDF_LOGE(\"%{public}s: failed to get stub of '%{public}s'\", __func__, desc);\n");
282     sb.Append(prefix + TAB + TAB).Append("return false;\n");
283     sb.Append(prefix + TAB).Append("}\n\n");
284     sb.Append(prefix + TAB).Append("if (HdfSbufWriteRemoteService(parcel, *stub) != HDF_SUCCESS) {\n");
285     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write remote service\", __func__);\n");
286     sb.Append(prefix + TAB + TAB).Append("return false;\n");
287     sb.Append(prefix + TAB).Append("}\n\n");
288     sb.Append(prefix + TAB).Append("return true;\n");
289     sb.Append(prefix).Append("}\n");
290 }
291 
EmitCReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const292 void ASTInterfaceType::EmitCReadMethods(StringBuilder &sb, const std::string &prefix,
293     const std::string &methodPrefix, bool isDecl) const
294 {
295     std::string methodName = StringHelper::Format("%sRead%s", methodPrefix.c_str(), name_.c_str());
296     if (isDecl) {
297         sb.Append(prefix).AppendFormat("static struct %s *%s(struct HdfSBuf *parcel);\n", name_.c_str(),
298             methodName.c_str());
299         return;
300     }
301     sb.Append(prefix).AppendFormat("static struct %s *%s(struct HdfSBuf *parcel)\n", name_.c_str(),
302         methodName.c_str());
303     sb.Append(prefix).Append("{\n");
304     sb.Append(prefix + TAB).Append("struct HdfRemoteService *remote = HdfSbufReadRemoteService(parcel);\n");
305     sb.Append(prefix + TAB).Append("if (remote == NULL) {\n");
306     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: ");
307     sb.AppendFormat(" failed to read remote service of '%s'\", __func__);\n", name_.c_str());
308     sb.Append(prefix + TAB + TAB).Append("return NULL;\n");
309     sb.Append(prefix + TAB).Append("}\n\n");
310     sb.Append(prefix + TAB).AppendFormat("return %sGet(remote);\n", name_.c_str());
311     sb.Append(prefix).Append("}\n");
312 }
313 } // namespace HDI
314 } // namespace OHOS
315