• 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_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