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#ifndef OHOS_IDL_CODE_EMITTER_H
17#define OHOS_IDL_CODE_EMITTER_H
18
19#include <set>
20
21#include "ast/ast.h"
22#include "util/autoptr.h"
23#include "util/light_refcount_base.h"
24#include "util/string_builder.h"
25
26namespace OHOS {
27namespace Idl {
28enum class HeaderFileType {
29    OWN_HEADER_FILE,
30    SYSTEM_HEADER_FILE,
31    C_STD_HEADER_FILE,
32    CPP_STD_HEADER_FILE,
33    OTHER_MODULES_HEADER_FILE,
34    OWN_MODULE_HEADER_FILE,
35};
36
37struct HeaderFile {
38    HeaderFile(HeaderFileType type, std::string fileName) : type_(type), fileName_(fileName) {}
39
40    struct Compare {
41        bool operator()(const HeaderFile &lhs, const HeaderFile &rhs) const
42        {
43            int compareRet = lhs.fileName_.compare(rhs.fileName_);
44            if (compareRet == 0) {
45                return false;
46            }
47
48            if (lhs.type_ != rhs.type_) {
49                return lhs.type_ < rhs.type_;
50            }
51
52            return compareRet < 0;
53        }
54    };
55
56    std::string ToString() const
57    {
58        switch (type_) {
59            case HeaderFileType::OWN_HEADER_FILE:
60            case HeaderFileType::OWN_MODULE_HEADER_FILE:
61                return StringHelper::Format("#include \"%s.h\"", fileName_.c_str());
62            case HeaderFileType::SYSTEM_HEADER_FILE:
63            case HeaderFileType::C_STD_HEADER_FILE:
64            case HeaderFileType::OTHER_MODULES_HEADER_FILE:
65                return StringHelper::Format("#include <%s.h>", fileName_.c_str());
66            case HeaderFileType::CPP_STD_HEADER_FILE:
67                return StringHelper::Format("#include <%s>", fileName_.c_str());
68            default:
69                return StringHelper::Format("//");
70        }
71    }
72
73    using HeaderFileSet = std::set<HeaderFile, HeaderFile::Compare>;
74
75    HeaderFileType type_;
76    std::string fileName_;
77};
78
79class CodeEmitter : public LightRefCountBase {
80public:
81    ~CodeEmitter() override = default;
82
83    virtual bool OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode) = 0;
84
85protected:
86    virtual bool ResolveDirectory(const std::string &targetDirectory) = 0;
87
88    virtual void EmitCode() = 0;
89
90    void EmitLicense(StringBuilder &sb);
91
92    bool NeedFlag(const AutoPtr<ASTMethod> &method) const;
93
94    std::string GetFileParentPath(const std::string &outDir) const;
95
96    std::string PackageToFilePath(const std::string &packageName) const;
97
98    std::string InterfaceToFilePath(const std::string &interfaceName) const;
99
100    std::string EmitMethodCmdID(const AutoPtr<ASTMethod> &method);
101
102    virtual void EmitInterfaceMethodCommands(StringBuilder &sb, const std::string &prefix);
103
104    /* add version prefix
105     * MajorVersion: 1
106     * MinorVersion: 0
107     * name: IFoo
108     * result: v1_0/ifoo.h
109     */
110    std::string EmitVersionHeaderName(const std::string &name) const;
111
112    // log tag macro of hdf
113    void EmitLogTagMacro(StringBuilder &sb, const std::string &name) const;
114
115    // file_name -> FILE_NAME
116    std::string ConstantName(const std::string &name) const;
117
118    // file_name -> FileName
119    std::string PascalName(const std::string &name) const;
120
121    // FileName -> file_name
122    std::string FileName(const std::string &name) const;
123
124    std::string GetNamespace(const std::string &fpnp) const;
125
126    void EmitHeadMacro(StringBuilder &sb, const std::string &fullName) const;
127
128    void EmitTailMacro(StringBuilder &sb, const std::string &fullName) const;
129
130    void EmitHeadExternC(StringBuilder &sb) const;
131
132    void EmitTailExternC(StringBuilder &sb) const;
133
134    std::string MacroName(const std::string &name) const;
135
136protected:
137    AutoPtr<AST> ast_ = nullptr;
138    AutoPtr<ASTInterfaceType> interface_ = nullptr;
139    std::string directory_;
140
141    std::string interfaceName_;
142    std::string interfaceFullName_;
143    std::string baseName_;
144    std::string proxyName_;
145    std::string proxyFullName_;
146    std::string stubName_;
147    std::string stubFullName_;
148    std::string deathRecipientName_;
149};
150} // namespace Idl
151} // namespace OHOS
152
153#endif // OHOS_IDL_CODE_EMITTER_H
154