• 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     if (methods_.size() > 0 && methods_.size() < SIZE_MAX) {
78         for (auto method : methods_) {
79             std::string info = method->Dump(prefix + "  ");
80             sb.Append(info);
81             if (method != methods_[methods_.size() - 1]) {
82                 sb.Append('\n');
83             }
84         }
85     }
86     sb.Append(prefix).Append("}\n");
87 
88     return sb.ToString();
89 }
90 
GetTypeKind()91 TypeKind ASTInterfaceType::GetTypeKind()
92 {
93     return TypeKind::TYPE_INTERFACE;
94 }
95 
GetFullName() const96 std::string ASTInterfaceType::GetFullName() const
97 {
98     return namespace_->ToString() + name_;
99 }
100 
EmitDescMacroName() const101 std::string ASTInterfaceType::EmitDescMacroName() const
102 {
103     return StringHelper::Format("%s_INTERFACE_DESC", StringHelper::StrToUpper(name_).c_str());
104 }
105 
EmitCType(TypeMode mode) const106 std::string ASTInterfaceType::EmitCType(TypeMode mode) const
107 {
108     switch (mode) {
109         case TypeMode::NO_MODE:
110             return StringHelper::Format("struct %s", name_.c_str());
111         case TypeMode::PARAM_IN:
112             return StringHelper::Format("struct %s*", name_.c_str());
113         case TypeMode::PARAM_OUT:
114             return StringHelper::Format("struct %s**", name_.c_str());
115         case TypeMode::LOCAL_VAR:
116             return StringHelper::Format("struct %s*", name_.c_str());
117         default:
118             return "unknow type";
119     }
120 }
121 
EmitCppType(TypeMode mode) const122 std::string ASTInterfaceType::EmitCppType(TypeMode mode) const
123 {
124     std::string pointerName = "sptr";
125     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
126         pointerName = "std::shared_ptr";
127     }
128     switch (mode) {
129         case TypeMode::NO_MODE:
130             return StringHelper::Format("%s<%s>", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
131         case TypeMode::PARAM_IN:
132             return StringHelper::Format(
133                 "const %s<%s>&", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
134         case TypeMode::PARAM_OUT:
135             return StringHelper::Format(
136                 "%s<%s>&", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
137         case TypeMode::LOCAL_VAR:
138             return StringHelper::Format("%s<%s>", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
139         default:
140             return "unknow type";
141     }
142 }
143 
EmitJavaType(TypeMode mode,bool isInnerType) const144 std::string ASTInterfaceType::EmitJavaType(TypeMode mode, bool isInnerType) const
145 {
146     return name_;
147 }
148 
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const149 void ASTInterfaceType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
150     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
151 {
152     sb.Append(prefix).AppendFormat("if (!WriteInterface(%s, %s, %s)) {\n", parcelName.c_str(),
153         EmitDescMacroName().c_str(), name.c_str());
154     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
155     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
156     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
157     sb.Append(prefix).Append("}\n");
158 }
159 
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) const160 void ASTInterfaceType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
161     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
162 {
163     sb.Append(prefix).AppendFormat("*%s = Read%s(%s);\n", name.c_str(), name_.c_str(), parcelName.c_str());
164     sb.Append(prefix).AppendFormat("if (*%s == NULL) {\n", name.c_str());
165     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
166     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
167     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
168     sb.Append(prefix).Append("}\n");
169 }
170 
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const171 void ASTInterfaceType::EmitCStubReadVar(const std::string &parcelName, const std::string &name,
172     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
173 {
174     sb.Append(prefix).AppendFormat("%s = Read%s(%s);\n", name.c_str(), name_.c_str(), parcelName.c_str());
175     sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
176     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
177     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
178     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
179     sb.Append(prefix).Append("}\n");
180 }
181 
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const182 void ASTInterfaceType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
183     const std::string &prefix, unsigned int innerLevel) const
184 {
185     sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
186     sb.Append(prefix + TAB)
187         .AppendFormat("HDF_LOGE(\"%%{public}s: parameter %s is nullptr!\", __func__);\n", name.c_str());
188     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
189     sb.Append(prefix).Append("}\n");
190     sb.Append("\n");
191     sb.Append(prefix).AppendFormat("if (!%s.WriteRemoteObject(", parcelName.c_str());
192     sb.AppendFormat("OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(%s, %s::GetDescriptor()))) {\n",
193         name.c_str(), GetNameWithNamespace(namespace_, name_).c_str());
194     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
195     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
196     sb.Append(prefix).Append("}\n");
197 }
198 
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const199 void ASTInterfaceType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
200     const std::string &prefix, bool initVariable, unsigned int innerLevel) const
201 {
202     std::string interfaceNamespace = GetNamespaceWithColon(namespace_, name_);
203     if (initVariable) {
204         sb.Append(prefix).AppendFormat("sptr<%s> %s;\n", GetNameWithNamespace(namespace_, name_).c_str(), name.c_str());
205     }
206     sb.Append(prefix).AppendFormat("sptr<IRemoteObject> %sRemote = %s.ReadRemoteObject();\n", name.c_str(),
207         parcelName.c_str());
208     sb.Append(prefix).AppendFormat("if (%sRemote == nullptr) {\n", name.c_str());
209     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: read an invalid remote object\", __func__);\n");
210     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
211     sb.Append(prefix).Append("}\n\n");
212     sb.Append(prefix).AppendFormat("%s = new %s(%sRemote);\n", name.c_str(),
213         (interfaceNamespace +
214         (StringHelper::StartWith(name_, "I") ? name_.substr(1) : name_) + "Proxy").c_str(), name.c_str());
215     sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
216     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to create interface object\", __func__);\n");
217     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
218     sb.Append(prefix).Append("}\n");
219 }
220 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const221 void ASTInterfaceType::EmitJavaWriteVar(
222     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
223 {
224     sb.Append(prefix).AppendFormat("%s.writeRemoteObject(%s.asObject());\n", parcelName.c_str(), name.c_str());
225 }
226 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const227 void ASTInterfaceType::EmitJavaReadVar(
228     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
229 {
230     std::string stubName = StringHelper::StartWith(name_, "I") ? (name_.substr(1) + "Stub") : (name_ + "Stub");
231     sb.Append(prefix).AppendFormat(
232         "%s = %s.asInterface(%s.readRemoteObject());\n", name.c_str(), stubName.c_str(), parcelName.c_str());
233 }
234 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const235 void ASTInterfaceType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
236     StringBuilder &sb, const std::string &prefix) const
237 {
238     std::string stubName = StringHelper::StartWith(name_, "I") ? (name_.substr(1) + "Stub") : (name_ + "Stub");
239     sb.Append(prefix).AppendFormat("%s %s = %s.asInterface(%s.readRemoteObject());\n",
240         EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), stubName.c_str(), parcelName.c_str());
241 }
242 
RegisterWriteMethod(Language language,SerMode mode,UtilMethodMap & methods) const243 void ASTInterfaceType::RegisterWriteMethod(Language language, SerMode mode, UtilMethodMap &methods) const
244 {
245     using namespace std::placeholders;
246     if (language == Language::C) {
247         methods.emplace("WriteInterface", std::bind(&ASTInterfaceType::EmitCWriteMethods, this, _1, _2, _3, _4));
248     }
249 }
250 
RegisterReadMethod(Language language,SerMode mode,UtilMethodMap & methods) const251 void ASTInterfaceType::RegisterReadMethod(Language language, SerMode mode, UtilMethodMap &methods) const
252 {
253     using namespace std::placeholders;
254 
255     switch (language) {
256         case Language::C: {
257             std::string methodName = StringHelper::Format("Read%s", name_.c_str());
258             methods.emplace(methodName, std::bind(&ASTInterfaceType::EmitCReadMethods, this, _1, _2, _3, _4));
259             break;
260         }
261         default:
262             break;
263     }
264 }
265 
EmitCWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const266 void ASTInterfaceType::EmitCWriteMethods(StringBuilder &sb, const std::string &prefix,
267     const std::string &methodPrefix, bool isDecl) const
268 {
269     std::string methodName = StringHelper::Format("%sWriteInterface", methodPrefix.c_str());
270     if (isDecl) {
271         sb.Append(prefix).AppendFormat("static bool %s(struct HdfSBuf *parcel, const char *desc, void *interface);\n",
272             methodName.c_str());
273         return;
274     }
275     sb.Append(prefix).AppendFormat("static bool %s(struct HdfSBuf *parcel, const char *desc, void *interface)\n",
276         methodName.c_str());
277     sb.Append(prefix).Append("{\n");
278     sb.Append(prefix + TAB).Append("if (interface == NULL) {\n");
279     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid interface object\", __func__);\n");
280     sb.Append(prefix + TAB + TAB).Append("return false;\n");
281     sb.Append(prefix + TAB).Append("}\n\n");
282     sb.Append(prefix + TAB).Append("struct HdfRemoteService **stub = StubCollectorGetOrNewObject(desc, interface);\n");
283     sb.Append(prefix + TAB).Append("if (stub == NULL) {\n");
284     sb.Append(prefix + TAB + TAB).Append(
285         "HDF_LOGE(\"%{public}s: failed to get stub of '%{public}s'\", __func__, desc);\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("if (HdfSbufWriteRemoteService(parcel, *stub) != HDF_SUCCESS) {\n");
289     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write remote service\", __func__);\n");
290     sb.Append(prefix + TAB + TAB).Append("return false;\n");
291     sb.Append(prefix + TAB).Append("}\n\n");
292     sb.Append(prefix + TAB).Append("return true;\n");
293     sb.Append(prefix).Append("}\n");
294 }
295 
EmitCReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const296 void ASTInterfaceType::EmitCReadMethods(StringBuilder &sb, const std::string &prefix,
297     const std::string &methodPrefix, bool isDecl) const
298 {
299     std::string methodName = StringHelper::Format("%sRead%s", methodPrefix.c_str(), name_.c_str());
300     if (isDecl) {
301         sb.Append(prefix).AppendFormat("static struct %s *%s(struct HdfSBuf *parcel);\n", name_.c_str(),
302             methodName.c_str());
303         return;
304     }
305     sb.Append(prefix).AppendFormat("static struct %s *%s(struct HdfSBuf *parcel)\n", name_.c_str(),
306         methodName.c_str());
307     sb.Append(prefix).Append("{\n");
308     sb.Append(prefix + TAB).Append("struct HdfRemoteService *remote = HdfSbufReadRemoteService(parcel);\n");
309     sb.Append(prefix + TAB).Append("if (remote == NULL) {\n");
310     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: ");
311     sb.AppendFormat(" failed to read remote service of '%s'\", __func__);\n", name_.c_str());
312     sb.Append(prefix + TAB + TAB).Append("return NULL;\n");
313     sb.Append(prefix + TAB).Append("}\n\n");
314     sb.Append(prefix + TAB).AppendFormat("return %sGet(remote);\n", name_.c_str());
315     sb.Append(prefix).Append("}\n");
316 }
317 } // namespace HDI
318 } // namespace OHOS
319