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_enum_type.h"
10 #include "util/string_builder.h"
11
12 namespace OHOS {
13 namespace HDI {
SetBaseType(const AutoPtr<ASTType> & baseType)14 void ASTEnumType::SetBaseType(const AutoPtr<ASTType> &baseType)
15 {
16 if (baseType == nullptr) {
17 return;
18 }
19 if (baseType->GetTypeKind() == TypeKind::TYPE_ENUM) {
20 AutoPtr<ASTEnumType> parentEnumType = dynamic_cast<ASTEnumType *>(baseType.Get());
21 std::vector<AutoPtr<ASTEnumValue>> parentMembers = parentEnumType->GetMembers();
22 for (auto member : parentMembers) {
23 members_.push_back(member);
24 }
25 parentType_= baseType;
26 baseType_ = parentEnumType->GetBaseType();
27 } else {
28 baseType_ = baseType;
29 }
30 }
31
AddMember(const AutoPtr<ASTEnumValue> & member)32 bool ASTEnumType::AddMember(const AutoPtr<ASTEnumValue> &member)
33 {
34 for (auto members : members_) {
35 if (member->GetName() == members->GetName()) {
36 return false;
37 }
38 }
39 members_.push_back(member);
40 return true;
41 }
42
GetBaseType()43 AutoPtr<ASTType> ASTEnumType::GetBaseType()
44 {
45 return baseType_;
46 }
47
IsEnumType()48 bool ASTEnumType::IsEnumType()
49 {
50 return true;
51 }
52
Dump(const std::string & prefix)53 std::string ASTEnumType::Dump(const std::string &prefix)
54 {
55 StringBuilder sb;
56 sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
57 if (baseType_ != nullptr) {
58 if (parentType_ != nullptr) {
59 sb.AppendFormat("enum %s : %s ", name_.c_str(), parentType_->ToString().c_str());
60 sb.AppendFormat(" : %s {\n", baseType_->ToString().c_str());
61 } else {
62 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseType_->ToString().c_str());
63 }
64 } else {
65 sb.AppendFormat("enum %s {\n", name_.c_str());
66 }
67
68 if (members_.size() > 0) {
69 for (auto it : members_) {
70 AutoPtr<ASTExpr> value = it->GetExprValue();
71 if (value == nullptr) {
72 sb.Append(" ").AppendFormat("%s,\n", it->GetName().c_str());
73 } else {
74 sb.Append(" ").AppendFormat("%s = %s,\n", it->GetName().c_str(), value->Dump("").c_str());
75 }
76 }
77 }
78
79 sb.Append(prefix).Append("};\n");
80
81 return sb.ToString();
82 }
83
GetTypeKind()84 TypeKind ASTEnumType::GetTypeKind()
85 {
86 return TypeKind::TYPE_ENUM;
87 }
88
EmitCType(TypeMode mode) const89 std::string ASTEnumType::EmitCType(TypeMode mode) const
90 {
91 switch (mode) {
92 case TypeMode::NO_MODE:
93 return StringHelper::Format("enum %s", name_.c_str());
94 case TypeMode::PARAM_IN:
95 return StringHelper::Format("enum %s", name_.c_str());
96 case TypeMode::PARAM_OUT:
97 return StringHelper::Format("enum %s*", name_.c_str());
98 case TypeMode::LOCAL_VAR:
99 return StringHelper::Format("enum %s", name_.c_str());
100 default:
101 return "unknow type";
102 }
103 }
104
EmitCppType(TypeMode mode) const105 std::string ASTEnumType::EmitCppType(TypeMode mode) const
106 {
107 switch (mode) {
108 case TypeMode::NO_MODE:
109 return StringHelper::Format("%s", GetNameWithNamespace(namespace_, name_).c_str());
110 case TypeMode::PARAM_IN:
111 return StringHelper::Format("%s", GetNameWithNamespace(namespace_, name_).c_str());
112 case TypeMode::PARAM_OUT:
113 return StringHelper::Format("%s&", GetNameWithNamespace(namespace_, name_).c_str());
114 case TypeMode::LOCAL_VAR:
115 return StringHelper::Format("%s", GetNameWithNamespace(namespace_, name_).c_str());
116 default:
117 return "unknow type";
118 }
119 }
120
EmitJavaType(TypeMode mode,bool isInnerType) const121 std::string ASTEnumType::EmitJavaType(TypeMode mode, bool isInnerType) const
122 {
123 // currently, Java does not support the enum type.
124 return "/";
125 }
126
EmitCTypeDecl() const127 std::string ASTEnumType::EmitCTypeDecl() const
128 {
129 StringBuilder sb;
130 sb.AppendFormat("enum %s {\n", name_.c_str());
131
132 for (auto it : members_) {
133 if (it->GetExprValue() == nullptr) {
134 sb.Append(TAB).AppendFormat("%s,\n", it->GetName().c_str());
135 } else {
136 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().c_str(), it->GetExprValue()->EmitCode().c_str());
137 }
138 }
139
140 sb.Append("};");
141 return sb.ToString();
142 }
143
EmitCppTypeDecl() const144 std::string ASTEnumType::EmitCppTypeDecl() const
145 {
146 StringBuilder sb;
147 if (baseType_ != nullptr) {
148 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseType_->EmitCppType().c_str());
149 } else {
150 sb.AppendFormat("enum %s {\n", name_.c_str());
151 }
152
153 for (auto it : members_) {
154 if (it->GetExprValue() == nullptr) {
155 sb.Append(TAB).AppendFormat("%s,\n", it->GetName().c_str());
156 } else {
157 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().c_str(), it->GetExprValue()->EmitCode().c_str());
158 }
159 }
160
161 sb.Append("};");
162 return sb.ToString();
163 }
164
EmitJavaTypeDecl() const165 std::string ASTEnumType::EmitJavaTypeDecl() const
166 {
167 StringBuilder sb;
168
169 return sb.ToString();
170 }
171
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const172 void ASTEnumType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
173 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
174 {
175 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(%s, (uint64_t)%s)) {\n", parcelName.c_str(), name.c_str());
176 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %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
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) const182 void ASTEnumType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
183 const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
184 {
185 std::string tmpVarName = "enumTmp";
186 sb.Append(prefix).Append("{\n");
187 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
188 sb.Append(prefix + TAB)
189 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
190 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
191 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
192 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
193 sb.Append(prefix + TAB).Append("}\n\n");
194 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", name.c_str());
195 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: invlid parameter %s\", __func__);\n",
196 name.c_str());
197 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
198 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
199 sb.Append(prefix + TAB).Append("}\n\n");
200 sb.Append(prefix + TAB).AppendFormat("*%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
201 sb.Append(prefix).Append("}\n");
202 }
203
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const204 void ASTEnumType::EmitCStubReadVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
205 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
206 {
207 std::string tmpVarName = "enumTmp";
208 sb.Append(prefix).Append("{\n");
209 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
210 sb.Append(prefix + TAB)
211 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
212 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
213 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
214 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
215 sb.Append(prefix + TAB).Append("}\n");
216 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
217 sb.Append(prefix).Append("}\n");
218 }
219
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const220 void ASTEnumType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
221 const std::string &prefix, unsigned int innerLevel) const
222 {
223 sb.Append(prefix).AppendFormat("if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(),
224 name.c_str());
225 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
226 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
227 sb.Append(prefix).Append("}\n");
228 }
229
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const230 void ASTEnumType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
231 const std::string &prefix, bool initVariable, unsigned int innerLevel) const
232 {
233 std::string tmpVarName = "enumTmp";
234 if (initVariable) {
235 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
236 EmitCType().c_str());
237 }
238 sb.Append(prefix).Append("{\n");
239 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
240 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
241 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
242 name.c_str());
243 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
244 sb.Append(prefix + TAB).Append("}\n");
245 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
246 tmpVarName.c_str());
247 sb.Append(prefix).Append("}\n");
248 }
249
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const250 void ASTEnumType::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
251 {
252 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(data, (uint64_t)%s)) {\n", name.c_str());
253 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
254 sb.Append(prefix + TAB).Append("return false;\n");
255 sb.Append(prefix).Append("}\n");
256 }
257
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const258 void ASTEnumType::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
259 const std::string &prefix, std::vector<std::string> &freeObjStatements) const
260 {
261 std::string tmpVarName = "enumTmp";
262 sb.Append(prefix).Append("{\n");
263 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
264 sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufReadUint64(data, &%s)) {\n", tmpVarName.c_str());
265 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
266 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
267 sb.Append(prefix + TAB).Append("}\n");
268 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
269 sb.Append(prefix).Append("}\n");
270 }
271
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const272 void ASTEnumType::EmitCppMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
273 const std::string &prefix, unsigned int innerLevel) const
274 {
275 sb.Append(prefix).AppendFormat(
276 "if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(), name.c_str());
277 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
278 sb.Append(prefix + TAB).Append("return false;\n");
279 sb.Append(prefix).Append("}\n");
280 }
281
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool emitType,unsigned int innerLevel) const282 void ASTEnumType::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
283 const std::string &prefix, bool emitType, unsigned int innerLevel) const
284 {
285 std::string tmpVarName = "enumTmp";
286 if (emitType) {
287 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
288 EmitCType().c_str());
289 }
290 sb.Append(prefix).Append("{\n");
291 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
292 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
293 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
294 name.c_str());
295 sb.Append(prefix + TAB + TAB).Append("return false;\n");
296 sb.Append(prefix + TAB).Append("}\n");
297 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
298 tmpVarName.c_str());
299 sb.Append(prefix).Append("}\n");
300 }
301 } // namespace HDI
302 } // namespace OHOS
303