1/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_
19
20#include <fstream>
21#include <string>
22
23namespace slang {
24
25// BitCode storage type
26enum BitCodeStorageType { BCST_APK_RESOURCE, BCST_JAVA_CODE, BCST_CPP_CODE };
27
28class RSSlangReflectUtils {
29public:
30  // Encode a binary bitcode file into a Java source file.
31  // rsFileName: the original .rs file name (with or without path).
32  // bc32FileName: path of the 32-bit bitcode file
33  // bc64FileName: path of the 64-bit bitcode file
34  // reflectPath: where to output the generated Java file, no package name in
35  // it.
36  // packageName: the package of the output Java file.
37  // verbose: whether or not to print out additional info about compilation.
38  // bcStorage: where to emit bitcode to (resource file or embedded).
39  struct BitCodeAccessorContext {
40    const char *rsFileName;
41    const char *bc32FileName;
42    const char *bc64FileName;
43    const char *reflectPath;
44    const char *packageName;
45    const std::string *licenseNote;
46    bool verbose;
47    BitCodeStorageType bcStorage;
48  };
49
50  // Return the stem of the file name, i.e., remove the dir and the extension.
51  // Eg, foo.ext -> foo
52  //     foo.bar.ext -> foo.bar
53  //     ./path/foo.ext -> foo
54  static std::string GetFileNameStem(const char *fileName);
55
56  // Compute a Java source file path from a given prefixPath and its package.
57  // Eg, given prefixPath=./foo/bar and packageName=com.x.y, then it returns
58  // ./foo/bar/com/x/y
59  static std::string ComputePackagedPath(const char *prefixPath,
60                                         const char *packageName);
61
62  // Compute Java class name from a .rs file name.
63  // Any non-alnum, non-underscore characters will be discarded.
64  // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
65  // "myRenderscript_file".
66  // rsFileName: the input .rs file name (with or without path).
67  static std::string JavaClassNameFromRSFileName(const char *rsFileName);
68
69  // Compute a bitcode file name (no extension) from a .rs file name.
70  // Because the bitcode file name may be used as Resource ID in the generated
71  // class (something like R.raw.<bitcode_filename>), Any non-alnum,
72  // non-underscore character will be discarded.
73  // The difference from JavaClassNameFromRSFileName() is that the result is
74  // converted to lowercase.
75  // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
76  // "myrenderscript_file"
77  // rsFileName: the input .rs file name (with or without path).
78  static std::string BCFileNameFromRSFileName(const char *rsFileName);
79
80  // Compute the bitcode-containing class name from a .rs filename.
81  // Any non-alnum, non-underscore characters will be discarded.
82  // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
83  // "myRenderscript_fileBitCode".
84  // rsFileName: the input .rs file name (with or without path).
85  static std::string JavaBitcodeClassNameFromRSFileName(const char *rsFileName);
86
87  // Generate the bit code accessor Java source file.
88  static bool GenerateJavaBitCodeAccessor(const BitCodeAccessorContext &context);
89};
90
91// Joins two sections of a path, inserting a separator if needed.
92// E.g. JoinPath("foo/bar", "baz/a.java") returns "foo/bar/baz/a.java",
93// JoinPath("foo", "/bar/baz") returns "foo/bar/baz", and
94// JoinPath("foo/", "/bar") returns "foo/bar".
95std::string JoinPath(const std::string &path1, const std::string &path2);
96
97/* Compute a safe root name from a .rs file name.  Any non-alphanumeric,
98 * non-underscore characters will be discarded.
99 * E.g. RootNameFromRSFileName("./foo/bar/my-Renderscript_file.rs") returns
100 * "myRenderscript_file".
101 */
102std::string RootNameFromRSFileName(const std::string &rsFileName);
103
104/* This class is used to generate one source file.  There will be one instance
105 * for each generated file.
106 */
107class GeneratedFile : public std::ofstream {
108public:
109  /* Starts the file by:
110   * - creating the parent directories (if needed),
111   * - opening the stream,
112   * - writing out the license,
113   * - writing a message that this file has been auto-generated.
114   * If optionalLicense is NULL, a default license is used.
115   */
116  bool startFile(const std::string &outPath, const std::string &outFileName,
117                 const std::string &sourceFileName,
118                 const std::string *optionalLicense, bool isJava, bool verbose);
119  void closeFile();
120
121  void increaseIndent(); // Increases the new line indentation by 4.
122  void decreaseIndent(); // Decreases the new line indentation by 4.
123  void comment(const std::string& s); // Outputs a multiline comment.
124
125  // Starts a control block.  This works both for Java and C++.
126  void startBlock() {
127    *this << " {\n";
128    increaseIndent();
129  }
130
131  // Ends a control block.
132  void endBlock(bool addSemicolon = false) {
133    decreaseIndent();
134    indent() << "}" << (addSemicolon ? ";" : "") << "\n\n";
135  }
136
137  /* Indents the line.  By returning *this, we can use like this:
138   *  mOut.ident() << "a = b;\n";
139   */
140  std::ofstream &indent() {
141    *this << mIndent;
142    return *this;
143  }
144
145private:
146  std::string mIndent; // The correct spacing at the beginning of each line.
147};
148
149} // namespace slang
150
151#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_  NOLINT
152