1ca0551cfSopenharmony_ci/*
2ca0551cfSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3ca0551cfSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ca0551cfSopenharmony_ci * you may not use this file except in compliance with the License.
5ca0551cfSopenharmony_ci * You may obtain a copy of the License at
6ca0551cfSopenharmony_ci *
7ca0551cfSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ca0551cfSopenharmony_ci *
9ca0551cfSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ca0551cfSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ca0551cfSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ca0551cfSopenharmony_ci * See the License for the specific language governing permissions and
13ca0551cfSopenharmony_ci * limitations under the License.
14ca0551cfSopenharmony_ci */
15ca0551cfSopenharmony_ci
16ca0551cfSopenharmony_ci#include "ast/ast.h"
17ca0551cfSopenharmony_ci
18ca0551cfSopenharmony_ci#include <cstdlib>
19ca0551cfSopenharmony_ci
20ca0551cfSopenharmony_ci#include "util/string_builder.h"
21ca0551cfSopenharmony_ci
22ca0551cfSopenharmony_cinamespace OHOS {
23ca0551cfSopenharmony_cinamespace Idl {
24ca0551cfSopenharmony_ciAST::TypeStringMap AST::basicTypes_ = {
25ca0551cfSopenharmony_ci    {"void",           new ASTVoidType()     },
26ca0551cfSopenharmony_ci    {"boolean",        new ASTBooleanType()     },
27ca0551cfSopenharmony_ci    {"byte",           new ASTByteType()        },
28ca0551cfSopenharmony_ci    {"short",          new ASTShortType()       },
29ca0551cfSopenharmony_ci    {"int",            new ASTIntegerType()     },
30ca0551cfSopenharmony_ci    {"long",           new ASTLongType()        },
31ca0551cfSopenharmony_ci    {"float",          new ASTFloatType()       },
32ca0551cfSopenharmony_ci    {"double",         new ASTDoubleType()      },
33ca0551cfSopenharmony_ci    {"String",         new ASTStringType()      },
34ca0551cfSopenharmony_ci    {"String16",       new ASTString16Type()    },
35ca0551cfSopenharmony_ci    {"char",           new ASTCharType()        },
36ca0551cfSopenharmony_ci    {"unsigned char",  new ASTUcharType()       },
37ca0551cfSopenharmony_ci    {"unsigned short", new ASTUshortType()      },
38ca0551cfSopenharmony_ci    {"unsigned int",   new ASTUintType()        },
39ca0551cfSopenharmony_ci    {"unsigned long",  new ASTUlongType()       },
40ca0551cfSopenharmony_ci    {"FileDescriptor", new ASTFdType()          },
41ca0551cfSopenharmony_ci    {"Ashmem",         new ASTAshmemType()      },
42ca0551cfSopenharmony_ci    {"NativeBuffer",   new ASTNativeBufferType()},
43ca0551cfSopenharmony_ci    {"Pointer",        new ASTPointerType()     },
44ca0551cfSopenharmony_ci};
45ca0551cfSopenharmony_ci
46ca0551cfSopenharmony_civoid AST::SetIdlFile(const std::string &idlFile)
47ca0551cfSopenharmony_ci{
48ca0551cfSopenharmony_ci    idlFilePath_ = idlFile;
49ca0551cfSopenharmony_ci#ifdef __MINGW32__
50ca0551cfSopenharmony_ci    size_t index = idlFilePath_.rfind('\\');
51ca0551cfSopenharmony_ci#else
52ca0551cfSopenharmony_ci    size_t index = idlFilePath_.rfind('/');
53ca0551cfSopenharmony_ci#endif
54ca0551cfSopenharmony_ci
55ca0551cfSopenharmony_ci    size_t end = idlFilePath_.rfind(".idl");
56ca0551cfSopenharmony_ci    if (end == std::string::npos) {
57ca0551cfSopenharmony_ci        end = idlFile.size();
58ca0551cfSopenharmony_ci    }
59ca0551cfSopenharmony_ci
60ca0551cfSopenharmony_ci    name_ = StringHelper::SubStr(idlFilePath_, (index == std::string::npos) ? 0 : (index + 1), end);
61ca0551cfSopenharmony_ci}
62ca0551cfSopenharmony_ci
63ca0551cfSopenharmony_civoid AST::SetFullName(const std::string &fullName)
64ca0551cfSopenharmony_ci{
65ca0551cfSopenharmony_ci    std::string name = fullName;
66ca0551cfSopenharmony_ci    size_t start = fullName.rfind("..");
67ca0551cfSopenharmony_ci    if (start != std::string::npos) {
68ca0551cfSopenharmony_ci        name = StringHelper::SubStr(fullName, start + strlen(".."));
69ca0551cfSopenharmony_ci    }
70ca0551cfSopenharmony_ci    size_t index = name.rfind('.');
71ca0551cfSopenharmony_ci    if (index != std::string::npos) {
72ca0551cfSopenharmony_ci        packageName_ = StringHelper::SubStr(name, 0, index);
73ca0551cfSopenharmony_ci        name_ = StringHelper::SubStr(name, index + 1);
74ca0551cfSopenharmony_ci    } else {
75ca0551cfSopenharmony_ci        packageName_ = "";
76ca0551cfSopenharmony_ci        name_ = name;
77ca0551cfSopenharmony_ci    }
78ca0551cfSopenharmony_ci}
79ca0551cfSopenharmony_ci
80ca0551cfSopenharmony_civoid AST::SetPackageName(const std::string &packageName)
81ca0551cfSopenharmony_ci{
82ca0551cfSopenharmony_ci    packageName_ = packageName;
83ca0551cfSopenharmony_ci    ParseNamespace(packageName_);
84ca0551cfSopenharmony_ci}
85ca0551cfSopenharmony_ci
86ca0551cfSopenharmony_ciAutoPtr<ASTNamespace> AST::ParseNamespace(const std::string &nspaceStr)
87ca0551cfSopenharmony_ci{
88ca0551cfSopenharmony_ci    AutoPtr<ASTNamespace> currNspace;
89ca0551cfSopenharmony_ci    size_t begin = 0;
90ca0551cfSopenharmony_ci    size_t index = 0;
91ca0551cfSopenharmony_ci    while ((index = nspaceStr.find('.', begin)) != std::string::npos) {
92ca0551cfSopenharmony_ci        std::string ns = StringHelper::SubStr(nspaceStr, begin, index);
93ca0551cfSopenharmony_ci        AutoPtr<ASTNamespace> nspace;
94ca0551cfSopenharmony_ci        if (currNspace == nullptr) {
95ca0551cfSopenharmony_ci            nspace = NewNameSpace(ns);
96ca0551cfSopenharmony_ci        } else {
97ca0551cfSopenharmony_ci            nspace = currNspace->FindNamespace(ns);
98ca0551cfSopenharmony_ci            if (nspace == nullptr) {
99ca0551cfSopenharmony_ci                nspace = new ASTNamespace(ns);
100ca0551cfSopenharmony_ci                currNspace->AddNamespace(nspace);
101ca0551cfSopenharmony_ci            }
102ca0551cfSopenharmony_ci        }
103ca0551cfSopenharmony_ci        currNspace = nspace;
104ca0551cfSopenharmony_ci        begin = index + 1;
105ca0551cfSopenharmony_ci    }
106ca0551cfSopenharmony_ci    if (currNspace == nullptr) {
107ca0551cfSopenharmony_ci        currNspace = NewNameSpace("");
108ca0551cfSopenharmony_ci    }
109ca0551cfSopenharmony_ci    return currNspace;
110ca0551cfSopenharmony_ci}
111ca0551cfSopenharmony_ci
112ca0551cfSopenharmony_ciAutoPtr<ASTNamespace> AST::NewNameSpace(std::string nameSpace)
113ca0551cfSopenharmony_ci{
114ca0551cfSopenharmony_ci    AutoPtr<ASTNamespace> currNspace = FindNamespace(nameSpace);
115ca0551cfSopenharmony_ci    if (currNspace == nullptr) {
116ca0551cfSopenharmony_ci        currNspace = new ASTNamespace(nameSpace);
117ca0551cfSopenharmony_ci        AddNamespace(currNspace);
118ca0551cfSopenharmony_ci    }
119ca0551cfSopenharmony_ci    return currNspace;
120ca0551cfSopenharmony_ci}
121ca0551cfSopenharmony_ci
122ca0551cfSopenharmony_civoid AST::AddNamespace(const AutoPtr<ASTNamespace> &nspace)
123ca0551cfSopenharmony_ci{
124ca0551cfSopenharmony_ci    if (nspace == nullptr) {
125ca0551cfSopenharmony_ci        return;
126ca0551cfSopenharmony_ci    }
127ca0551cfSopenharmony_ci    namespaces_.push_back(nspace);
128ca0551cfSopenharmony_ci}
129ca0551cfSopenharmony_ci
130ca0551cfSopenharmony_ciAutoPtr<ASTNamespace> AST::FindNamespace(const std::string &nspaceStr)
131ca0551cfSopenharmony_ci{
132ca0551cfSopenharmony_ci    for (auto nspace : namespaces_) {
133ca0551cfSopenharmony_ci        if (nspace->ToShortString() == nspaceStr) {
134ca0551cfSopenharmony_ci            return nspace;
135ca0551cfSopenharmony_ci        }
136ca0551cfSopenharmony_ci    }
137ca0551cfSopenharmony_ci    return nullptr;
138ca0551cfSopenharmony_ci}
139ca0551cfSopenharmony_ci
140ca0551cfSopenharmony_ciAutoPtr<ASTNamespace> AST::GetNamespace(size_t index)
141ca0551cfSopenharmony_ci{
142ca0551cfSopenharmony_ci    if (index >= namespaces_.size()) {
143ca0551cfSopenharmony_ci        return nullptr;
144ca0551cfSopenharmony_ci    }
145ca0551cfSopenharmony_ci
146ca0551cfSopenharmony_ci    return namespaces_[index];
147ca0551cfSopenharmony_ci}
148ca0551cfSopenharmony_ci
149ca0551cfSopenharmony_civoid AST::AddInterfaceDef(const AutoPtr<ASTInterfaceType> &interface)
150ca0551cfSopenharmony_ci{
151ca0551cfSopenharmony_ci    if (interface == nullptr) {
152ca0551cfSopenharmony_ci        return;
153ca0551cfSopenharmony_ci    }
154ca0551cfSopenharmony_ci
155ca0551cfSopenharmony_ci    interfaceDefs_.push_back(interface);
156ca0551cfSopenharmony_ci    AddType(interface.Get());
157ca0551cfSopenharmony_ci}
158ca0551cfSopenharmony_ci
159ca0551cfSopenharmony_ciAutoPtr<ASTInterfaceType> AST::GetInterfaceDef(size_t index)
160ca0551cfSopenharmony_ci{
161ca0551cfSopenharmony_ci    if (index >= interfaceDefs_.size()) {
162ca0551cfSopenharmony_ci        return nullptr;
163ca0551cfSopenharmony_ci    }
164ca0551cfSopenharmony_ci
165ca0551cfSopenharmony_ci    return interfaceDefs_[index];
166ca0551cfSopenharmony_ci}
167ca0551cfSopenharmony_ci
168ca0551cfSopenharmony_ciAutoPtr<ASTSequenceableType> AST::GetSequenceableDef(size_t index)
169ca0551cfSopenharmony_ci{
170ca0551cfSopenharmony_ci    if (index >= sequenceableDefs_.size()) {
171ca0551cfSopenharmony_ci        return nullptr;
172ca0551cfSopenharmony_ci    }
173ca0551cfSopenharmony_ci
174ca0551cfSopenharmony_ci    return sequenceableDefs_[index];
175ca0551cfSopenharmony_ci}
176ca0551cfSopenharmony_ci
177ca0551cfSopenharmony_civoid AST::AddSequenceableDef(const AutoPtr<ASTSequenceableType> &sequenceable)
178ca0551cfSopenharmony_ci{
179ca0551cfSopenharmony_ci    if (sequenceable == nullptr) {
180ca0551cfSopenharmony_ci        return;
181ca0551cfSopenharmony_ci    }
182ca0551cfSopenharmony_ci
183ca0551cfSopenharmony_ci    sequenceableDefs_.push_back(sequenceable);
184ca0551cfSopenharmony_ci    AddType(sequenceable.Get());
185ca0551cfSopenharmony_ci}
186ca0551cfSopenharmony_ci
187ca0551cfSopenharmony_ciint AST::IndexOf(ASTInterfaceType* interface)
188ca0551cfSopenharmony_ci{
189ca0551cfSopenharmony_ci    for (size_t i = 0; i < interfaceDefs_.size(); i++) {
190ca0551cfSopenharmony_ci        if (interfaceDefs_[i] == interface) {
191ca0551cfSopenharmony_ci            return i;
192ca0551cfSopenharmony_ci        }
193ca0551cfSopenharmony_ci    }
194ca0551cfSopenharmony_ci    return -1;
195ca0551cfSopenharmony_ci}
196ca0551cfSopenharmony_ci
197ca0551cfSopenharmony_ciint AST::IndexOf(ASTSequenceableType* sequenceable)
198ca0551cfSopenharmony_ci{
199ca0551cfSopenharmony_ci    for (size_t i = 0; i < sequenceableDefs_.size(); i++) {
200ca0551cfSopenharmony_ci        if (sequenceableDefs_[i] == sequenceable) {
201ca0551cfSopenharmony_ci            return i;
202ca0551cfSopenharmony_ci        }
203ca0551cfSopenharmony_ci    }
204ca0551cfSopenharmony_ci    return -1;
205ca0551cfSopenharmony_ci}
206ca0551cfSopenharmony_ci
207ca0551cfSopenharmony_ciint AST::IndexOf(ASTType* type)
208ca0551cfSopenharmony_ci{
209ca0551cfSopenharmony_ci    int i = 0;
210ca0551cfSopenharmony_ci    for (auto it = types_.begin(); it != types_.end(); ++it, ++i) {
211ca0551cfSopenharmony_ci        if (it->second == type) {
212ca0551cfSopenharmony_ci            return i;
213ca0551cfSopenharmony_ci        }
214ca0551cfSopenharmony_ci    }
215ca0551cfSopenharmony_ci    return -1;
216ca0551cfSopenharmony_ci}
217ca0551cfSopenharmony_ci
218ca0551cfSopenharmony_civoid AST::AddType(const AutoPtr<ASTType> &type)
219ca0551cfSopenharmony_ci{
220ca0551cfSopenharmony_ci    if (type == nullptr) {
221ca0551cfSopenharmony_ci        return;
222ca0551cfSopenharmony_ci    }
223ca0551cfSopenharmony_ci
224ca0551cfSopenharmony_ci    types_[type->ToString()] = type;
225ca0551cfSopenharmony_ci}
226ca0551cfSopenharmony_ci
227ca0551cfSopenharmony_ciAutoPtr<ASTType> AST::FindType(const std::string &typeName, bool lookImports)
228ca0551cfSopenharmony_ci{
229ca0551cfSopenharmony_ci    if (typeName.empty()) {
230ca0551cfSopenharmony_ci        return nullptr;
231ca0551cfSopenharmony_ci    }
232ca0551cfSopenharmony_ci
233ca0551cfSopenharmony_ci    for (const auto &type : types_) {
234ca0551cfSopenharmony_ci        if ((typeName.find('.') == std::string::npos && type.second->GetName() == typeName) ||
235ca0551cfSopenharmony_ci            type.first == typeName) {
236ca0551cfSopenharmony_ci            return type.second;
237ca0551cfSopenharmony_ci        }
238ca0551cfSopenharmony_ci    }
239ca0551cfSopenharmony_ci
240ca0551cfSopenharmony_ci    auto basicTypePair = basicTypes_.find(typeName);
241ca0551cfSopenharmony_ci    if (basicTypePair != basicTypes_.end()) {
242ca0551cfSopenharmony_ci        return basicTypePair->second;
243ca0551cfSopenharmony_ci    }
244ca0551cfSopenharmony_ci
245ca0551cfSopenharmony_ci    if (!lookImports) {
246ca0551cfSopenharmony_ci        return nullptr;
247ca0551cfSopenharmony_ci    }
248ca0551cfSopenharmony_ci
249ca0551cfSopenharmony_ci    AutoPtr<ASTType> type = nullptr;
250ca0551cfSopenharmony_ci    for (const auto &importPair : imports_) {
251ca0551cfSopenharmony_ci        type = importPair.second->FindType(typeName, false);
252ca0551cfSopenharmony_ci        if (type != nullptr) {
253ca0551cfSopenharmony_ci            break;
254ca0551cfSopenharmony_ci        }
255ca0551cfSopenharmony_ci    }
256ca0551cfSopenharmony_ci    return type;
257ca0551cfSopenharmony_ci}
258ca0551cfSopenharmony_ci
259ca0551cfSopenharmony_civoid AST::AddTypeDefinition(const AutoPtr<ASTType> &type)
260ca0551cfSopenharmony_ci{
261ca0551cfSopenharmony_ci    if (type == nullptr) {
262ca0551cfSopenharmony_ci        return;
263ca0551cfSopenharmony_ci    }
264ca0551cfSopenharmony_ci
265ca0551cfSopenharmony_ci    AddType(type);
266ca0551cfSopenharmony_ci    typeDefinitions_.push_back(type);
267ca0551cfSopenharmony_ci}
268ca0551cfSopenharmony_ci
269ca0551cfSopenharmony_ciAutoPtr<ASTType> AST::GetTypeDefintion(size_t index)
270ca0551cfSopenharmony_ci{
271ca0551cfSopenharmony_ci    if (index >= typeDefinitions_.size()) {
272ca0551cfSopenharmony_ci        return nullptr;
273ca0551cfSopenharmony_ci    }
274ca0551cfSopenharmony_ci    return typeDefinitions_[index];
275ca0551cfSopenharmony_ci}
276ca0551cfSopenharmony_ci
277ca0551cfSopenharmony_cistd::string AST::Dump(const std::string &prefix)
278ca0551cfSopenharmony_ci{
279ca0551cfSopenharmony_ci    StringBuilder sb;
280ca0551cfSopenharmony_ci
281ca0551cfSopenharmony_ci    sb.Append(prefix);
282ca0551cfSopenharmony_ci    if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
283ca0551cfSopenharmony_ci        sb.Append("Module[");
284ca0551cfSopenharmony_ci    } else {
285ca0551cfSopenharmony_ci        sb.Append("AST[");
286ca0551cfSopenharmony_ci    }
287ca0551cfSopenharmony_ci    sb.Append("name: ").Append(name_).Append(" ");
288ca0551cfSopenharmony_ci    sb.Append("file: ").Append(idlFilePath_);
289ca0551cfSopenharmony_ci    sb.Append("]\n");
290ca0551cfSopenharmony_ci
291ca0551cfSopenharmony_ci    if (!packageName_.empty()) {
292ca0551cfSopenharmony_ci        sb.Append("package ").Append(packageName_).Append(";");
293ca0551cfSopenharmony_ci        sb.Append('\n');
294ca0551cfSopenharmony_ci        sb.Append('\n');
295ca0551cfSopenharmony_ci    }
296ca0551cfSopenharmony_ci
297ca0551cfSopenharmony_ci    if (imports_.size() > 0) {
298ca0551cfSopenharmony_ci        std::string Keyword = "import";
299ca0551cfSopenharmony_ci        if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
300ca0551cfSopenharmony_ci            Keyword = "sequenceable";
301ca0551cfSopenharmony_ci        }
302ca0551cfSopenharmony_ci        for (const auto &import : imports_) {
303ca0551cfSopenharmony_ci            sb.AppendFormat("%s %s;\n", Keyword.c_str(), import.first.c_str());
304ca0551cfSopenharmony_ci        }
305ca0551cfSopenharmony_ci        sb.Append("\n");
306ca0551cfSopenharmony_ci    }
307ca0551cfSopenharmony_ci
308ca0551cfSopenharmony_ci    if (typeDefinitions_.size() > 0) {
309ca0551cfSopenharmony_ci        for (auto type : typeDefinitions_) {
310ca0551cfSopenharmony_ci            std::string info = type->Dump("");
311ca0551cfSopenharmony_ci            sb.Append(info).Append("\n");
312ca0551cfSopenharmony_ci        }
313ca0551cfSopenharmony_ci    }
314ca0551cfSopenharmony_ci
315ca0551cfSopenharmony_ci    if (interfaceDefs_.size() > 0) {
316ca0551cfSopenharmony_ci        for (auto type : interfaceDefs_) {
317ca0551cfSopenharmony_ci            if (type->IsExternal()) {
318ca0551cfSopenharmony_ci                std::string info = type->Dump("");
319ca0551cfSopenharmony_ci                sb.Append(info).Append("\n");
320ca0551cfSopenharmony_ci            }
321ca0551cfSopenharmony_ci        }
322ca0551cfSopenharmony_ci
323ca0551cfSopenharmony_ci        for (auto type : interfaceDefs_) {
324ca0551cfSopenharmony_ci            if (!type->IsExternal()) {
325ca0551cfSopenharmony_ci                std::string info = type->Dump("");
326ca0551cfSopenharmony_ci                sb.Append(info).Append("\n");
327ca0551cfSopenharmony_ci            }
328ca0551cfSopenharmony_ci        }
329ca0551cfSopenharmony_ci    }
330ca0551cfSopenharmony_ci
331ca0551cfSopenharmony_ci    return sb.ToString();
332ca0551cfSopenharmony_ci}
333ca0551cfSopenharmony_ci
334ca0551cfSopenharmony_cibool AST::AddImport(const AutoPtr<AST> &importAst)
335ca0551cfSopenharmony_ci{
336ca0551cfSopenharmony_ci    if (imports_.find(importAst->GetFullName()) != imports_.end()) {
337ca0551cfSopenharmony_ci        return false;
338ca0551cfSopenharmony_ci    }
339ca0551cfSopenharmony_ci
340ca0551cfSopenharmony_ci    imports_[importAst->GetFullName()] = importAst;
341ca0551cfSopenharmony_ci
342ca0551cfSopenharmony_ci    return true;
343ca0551cfSopenharmony_ci}
344ca0551cfSopenharmony_ci
345ca0551cfSopenharmony_civoid AST::SetVersion(size_t &majorVer, size_t &minorVer)
346ca0551cfSopenharmony_ci{
347ca0551cfSopenharmony_ci    majorVersion_ = majorVer;
348ca0551cfSopenharmony_ci    minorVersion_ = minorVer;
349ca0551cfSopenharmony_ci}
350ca0551cfSopenharmony_ci
351ca0551cfSopenharmony_cibool AST::IsValid()
352ca0551cfSopenharmony_ci{
353ca0551cfSopenharmony_ci    if (name_.empty()) {
354ca0551cfSopenharmony_ci        return false;
355ca0551cfSopenharmony_ci    }
356ca0551cfSopenharmony_ci
357ca0551cfSopenharmony_ci    return interfaceDefs_.size() > 0;
358ca0551cfSopenharmony_ci}
359ca0551cfSopenharmony_ci
360ca0551cfSopenharmony_ci} // namespace Idl
361ca0551cfSopenharmony_ci} // namespace OHOS