1/**
2 * Copyright (c) 2022 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 "arena_allocator.h"
17#include "mergeProgram.h"
18#include "options.h"
19#include "protobufSnapshotGenerator.h"
20
21#include <assembly-emitter.h>
22#include <mem/pool_manager.h>
23
24namespace panda::proto {
25using mem::MemConfig;
26
27class ProtoMemManager {
28public:
29    explicit ProtoMemManager()
30    {
31        constexpr auto COMPILER_SIZE = 512_MB;
32
33        MemConfig::Initialize(0, 0, COMPILER_SIZE, 0);
34        PoolManager::Initialize(PoolType::MMAP);
35    }
36
37    NO_COPY_SEMANTIC(ProtoMemManager);
38    NO_MOVE_SEMANTIC(ProtoMemManager);
39
40    ~ProtoMemManager()
41    {
42        PoolManager::Finalize();
43        MemConfig::Finalize();
44    }
45};
46
47int Run(int argc, const char **argv)
48{
49    auto options = std::make_unique<Options>();
50    if (!options->Parse(argc, argv)) {
51        std::cerr << options->ErrorMsg() << std::endl;
52        return 1;
53    }
54
55    std::string protoPathInput = options->protoPathInput();
56    std::string protoBinSuffix = options->protoBinSuffix();
57    std::string outputFilePath = options->outputFilePath();
58    if (outputFilePath.empty()) {
59        outputFilePath = panda::os::file::File::GetExecutablePath().Value();
60    }
61
62    std::vector<std::string> protoFiles;
63    if (!MergeProgram::CollectProtoFiles(protoPathInput, protoBinSuffix, protoFiles)) {
64        return 1;
65    }
66
67    panda::ArenaAllocator allocator(panda::SpaceType::SPACE_TYPE_COMPILER, nullptr, true);
68
69    std::vector<panda::pandasm::Program *> programs;
70    programs.reserve(protoFiles.size());
71    for (size_t i = 0; i < protoFiles.size(); i++) {
72        auto *prog = allocator.New<panda::pandasm::Program>();
73        programs.emplace_back(prog);
74    }
75
76    size_t idx = 0;
77    for (auto &protoFile : protoFiles) {
78        proto::ProtobufSnapshotGenerator::GenerateProgram(protoFile, *(programs[idx++]), &allocator);
79    }
80
81    std::string outputFileName = outputFilePath.append(panda::os::file::File::GetPathDelim()).
82        append(options->outputFileName());
83    if (!panda::pandasm::AsmEmitter::EmitPrograms(panda::os::file::File::GetExtendedFilePath(outputFileName), programs,
84        true)) {
85        return 1;
86    }
87
88    return 0;
89}
90} // namespace panda::proto
91
92int main(int argc, const char **argv)
93{
94    panda::proto::ProtoMemManager mm;
95    return panda::proto::Run(argc, argv);
96}
97