1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "codegen/code_generator.h"
17 #include "parser/parser.h"
18 #include "preprocessor/preprocessor.h"
19 #include "util/file.h"
20 #include "util/logger.h"
21 #include "util/options.h"
22 #include "hash/hash.h"
23 #include "metadata/metadata_builder.h"
24 #include "metadata/metadata_dumper.h"
25 #include "metadata/metadata_reader.h"
26 #include "metadata/metadata_serializer.h"
27 
28 using namespace OHOS::Idl;
29 
FileParse(Parser & parser)30 static int FileParse(Parser &parser)
31 {
32     std::vector<FileDetail> fileDetails;
33     if (!Preprocessor::Preprocess(fileDetails)) {
34         Logger::E(TAG, "failed to preprocess");
35         return -1;
36     }
37 
38     if (!parser.Parse(fileDetails)) {
39         Logger::E(TAG, "failed to parse file");
40         return -1;
41     }
42 
43     return 0;
44 }
45 
DumpAst(const StrAstMap & allAst)46 static void DumpAst(const StrAstMap &allAst)
47 {
48     const Options &options = Options::GetInstance();
49     if (!options.DoDumpAST()) {
50         return;
51     }
52     for (const auto &astPair : allAst) {
53         AutoPtr<AST> ast = astPair.second;
54         if ((options.GetInterfaceType() == InterfaceType::SA) &&
55             (ast->GetASTFileType() != ASTFileType::AST_IFACE)) {
56             continue;
57         }
58         if (astPair.second != nullptr) {
59             printf("%s\n", astPair.second->Dump("").c_str());
60         }
61     }
62 }
63 
DumpMetaData(const StrAstMap & allAst)64 static int DumpMetaData(const StrAstMap &allAst)
65 {
66     Options &options = Options::GetInstance();
67     if ((options.GetInterfaceType() != InterfaceType::SA)) {
68         return 0;
69     }
70 
71     AutoPtr<AST> ast;
72     for (const auto &astPair : allAst) {
73         ast = astPair.second;
74         if (ast->GetASTFileType() == ASTFileType::AST_IFACE) {
75             break;
76         }
77     }
78     MetadataBuilder builder(ast);
79     std::shared_ptr<MetaComponent> metadata = builder.Build();
80     if (metadata == nullptr) {
81         Logger::E(TAG, "Generate metadata failed.");
82         return -1;
83     }
84 
85     if (options.DoDumpMetadata()) {
86         MetadataDumper dumper(metadata.get());
87         printf("%s", dumper.Dump("").c_str());
88     }
89 
90     if (options.DoSaveMetadata()) {
91         File metadataFile(options.GetMetadataFile(), File::WRITE);
92         if (!metadataFile.IsValid()) {
93             Logger::E(TAG, "Create metadata file failed.");
94             return -1;
95         }
96 
97         MetadataSerializer serializer(metadata.get());
98         serializer.Serialize();
99         uintptr_t data = serializer.GetData();
100         int size = serializer.GetDataSize();
101 
102         metadataFile.WriteData(reinterpret_cast<void*>(data), size);
103         metadataFile.Flush();
104         metadataFile.Close();
105     }
106     return 0;
107 }
108 
ReadMetaData(StrAstMap & astList)109 static int ReadMetaData(StrAstMap &astList)
110 {
111     const Options &options = Options::GetInstance();
112     if ((options.GetInterfaceType() != InterfaceType::SA) || options.DoCompile()) {
113         return 0;
114     }
115     std::string metadataFile = options.GetMetadataFile();
116     std::shared_ptr<MetaComponent> metadata = MetadataReader::ReadMetadataFromFile(metadataFile);
117     if (metadata == nullptr) {
118         Logger::E(TAG, "Get metadata from \"%s\" failed.", metadataFile.c_str());
119         return -1;
120     }
121 
122     MetadataReader reader(metadata.get());
123     astList = reader.ReadMetadataToAst();
124     return 0;
125 }
126 
main(int argc,char ** argv)127 int main(int argc, char **argv)
128 {
129     Options &options = Options::GetInstance();
130     if (!options.Parse(argc, argv)) {
131         return -1;
132     }
133 
134     if (options.DoShowUsage()) {
135         options.ShowUsage();
136         return 0;
137     }
138     if (options.DoShowVersion()) {
139         options.ShowVersion();
140         return 0;
141     }
142     if (options.HasWarning()) {
143         options.ShowWarning();
144     }
145 
146     if (options.DoGetHashKey()) {
147         return Hash::GenHashKey() ? 0 : -1;
148     }
149 
150     StrAstMap astList;
151     Parser parser;
152     if (options.DoCompile()) {
153         if (FileParse(parser) != 0) {
154             return -1;
155         }
156 
157         astList = parser.GetAllAst();
158         DumpAst(astList);
159 
160         if (DumpMetaData(astList) != 0) {
161             return -1;
162         }
163     }
164 
165     if (!options.DoGenerateCode()) {
166         return 0;
167     }
168 
169     if (ReadMetaData(astList) != 0) {
170         return -1;
171     }
172 
173     if (!CodegenBuilder::GetInstance().Generate(astList)) {
174         Logger::E(TAG, "failed to generate code");
175         return -1;
176     }
177     return 0;
178 }