slang_rs_reflection.h revision 2ce118e843fcbd53488b503933136bb4fdbdfbc1
1/*
2 * Copyright 2010-2012, 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_RS_REFLECTION_H_ // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_
19
20#include <fstream>
21#include <iostream>
22#include <map>
23#include <set>
24#include <string>
25#include <vector>
26
27#include "llvm/ADT/StringExtras.h"
28
29#include "slang_assert.h"
30#include "slang_rs_export_type.h"
31
32namespace slang {
33
34class RSContext;
35class RSExportVar;
36class RSExportFunc;
37class RSExportForEach;
38
39class RSReflectionJava {
40private:
41  const RSContext *mRSContext;
42
43  std::string mLastError;
44  std::vector<std::string> *mGeneratedFileNames;
45
46  inline void setError(const std::string &Error) { mLastError = Error; }
47
48  class Context {
49  private:
50    static const char *const ApacheLicenseNote;
51
52    bool mVerbose;
53
54    std::string mOutputPathBase;
55
56    std::string mInputRSFile;
57
58    std::string mPackageName;
59    std::string mRSPackageName;
60    std::string mResourceId;
61    std::string mPaddingPrefix;
62
63    std::string mClassName;
64
65    std::string mLicenseNote;
66
67    bool mUseStdout;
68
69    bool mEmbedBitcodeInJava;
70
71    std::string mIndent;
72
73    int mPaddingFieldIndex;
74
75    int mNextExportVarSlot;
76    int mNextExportFuncSlot;
77    int mNextExportForEachSlot;
78
79    // A mapping from a field in a record type to its index in the rsType
80    // instance. Only used when generates TypeClass (ScriptField_*).
81    typedef std::map<const RSExportRecordType::Field *, unsigned>
82    FieldIndexMapTy;
83    FieldIndexMapTy mFieldIndexMap;
84    // Field index of current processing TypeClass.
85    unsigned mFieldIndex;
86
87    inline void clear() {
88      mClassName = "";
89      mIndent = "";
90      mPaddingFieldIndex = 1;
91      mNextExportVarSlot = 0;
92      mNextExportFuncSlot = 0;
93      mNextExportForEachSlot = 0;
94    }
95
96    bool openClassFile(const std::string &ClassName, std::string &ErrorMsg);
97
98  public:
99    typedef enum {
100      AM_Public,
101      AM_Protected,
102      AM_Private,
103      AM_PublicSynchronized
104    } AccessModifier;
105
106    mutable std::ofstream mOF;
107
108    // Generated RS Elements for type-checking code.
109    std::set<std::string> mTypesToCheck;
110
111    // Generated FieldPackers for unsigned setters/validation.
112    std::set<std::string> mFieldPackerTypes;
113
114    bool addTypeNameForElement(const std::string &TypeName);
115    bool addTypeNameForFieldPacker(const std::string &TypeName);
116
117    static const char *AccessModifierStr(AccessModifier AM);
118
119    Context(const std::string &OutputPathBase, const std::string &InputRSFile,
120            const std::string &PackageName, const std::string &RSPackageName,
121            const std::string &ResourceId, const std::string &PaddingPrefix,
122            bool UseStdout, bool EmbedBitcodeInJava)
123        : mVerbose(true), mOutputPathBase(OutputPathBase),
124          mInputRSFile(InputRSFile), mPackageName(PackageName),
125          mRSPackageName(RSPackageName), mResourceId(ResourceId),
126          mPaddingPrefix(PaddingPrefix), mLicenseNote(ApacheLicenseNote),
127          mUseStdout(UseStdout), mEmbedBitcodeInJava(EmbedBitcodeInJava) {
128      clear();
129      resetFieldIndex();
130      clearFieldIndexMap();
131    }
132
133    inline std::string &getInputRSFile() { return mInputRSFile; }
134
135    inline std::ostream &out() const {
136      return ((mUseStdout) ? std::cout : mOF);
137    }
138    inline std::ostream &indent() const {
139      out() << mIndent;
140      return out();
141    }
142
143    inline void incIndentLevel() { mIndent.append(4, ' '); }
144
145    inline void decIndentLevel() {
146      slangAssert(getIndentLevel() > 0 && "No indent");
147      mIndent.erase(0, 4);
148    }
149
150    inline int getIndentLevel() { return (mIndent.length() >> 2); }
151
152    inline bool getEmbedBitcodeInJava() const { return mEmbedBitcodeInJava; }
153
154    inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
155
156    inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
157    inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
158
159    // Will remove later due to field name information is not necessary for
160    // C-reflect-to-Java
161    inline std::string createPaddingField() {
162      return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
163    }
164
165    inline void setLicenseNote(const std::string &LicenseNote) {
166      mLicenseNote = LicenseNote;
167    }
168
169    bool startClass(AccessModifier AM, bool IsStatic,
170                    const std::string &ClassName, const char *SuperClassName,
171                    std::string &ErrorMsg);
172    void endClass();
173
174    void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
175                       const std::string &FunctionName, int Argc, ...);
176
177    typedef std::vector<std::pair<std::string, std::string>> ArgTy;
178    void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
179                       const std::string &FunctionName, const ArgTy &Args);
180    void endFunction();
181
182    void startBlock(bool ShouldIndent = false);
183    void endBlock();
184
185    inline const std::string &getPackageName() const { return mPackageName; }
186    inline const std::string &getRSPackageName() const {
187      return mRSPackageName;
188    }
189    inline const std::string &getClassName() const { return mClassName; }
190    inline const std::string &getResourceId() const { return mResourceId; }
191
192    void startTypeClass(const std::string &ClassName);
193    void endTypeClass();
194
195    inline void incFieldIndex() { mFieldIndex++; }
196
197    inline void resetFieldIndex() { mFieldIndex = 0; }
198
199    inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
200      slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
201                  "Nested structure never occurs in C language.");
202      mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
203    }
204
205    inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
206      FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
207      slangAssert((I != mFieldIndexMap.end()) &&
208                  "Requesting field is out of scope.");
209      return I->second;
210    }
211
212    inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
213  };
214
215  bool genScriptClass(Context &C, const std::string &ClassName,
216                      std::string &ErrorMsg);
217  void genScriptClassConstructor(Context &C);
218
219  static void genInitBoolExportVariable(Context &C, const std::string &VarName,
220                                        const clang::APValue &Val);
221  static void genInitPrimitiveExportVariable(Context &C,
222                                             const std::string &VarName,
223                                             const clang::APValue &Val);
224  static void genInitExportVariable(Context &C, const RSExportType *ET,
225                                    const std::string &VarName,
226                                    const clang::APValue &Val);
227  void genExportVariable(Context &C, const RSExportVar *EV);
228  void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
229  void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
230  void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
231  void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
232  void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
233  void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
234  void genPrivateExportVariable(Context &C, const std::string &TypeName,
235                                const std::string &VarName);
236  void genSetExportVariable(Context &C, const std::string &TypeName,
237                            const RSExportVar *EV);
238  void genGetExportVariable(Context &C, const std::string &TypeName,
239                            const std::string &VarName);
240  void genGetFieldID(Context &C, const std::string &VarName);
241
242  void genExportFunction(Context &C, const RSExportFunc *EF);
243
244  void genExportForEach(Context &C, const RSExportForEach *EF);
245
246  static void genTypeCheck(Context &C, const RSExportType *ET,
247                           const char *VarName);
248
249  static void genTypeInstanceFromPointer(Context &C, const RSExportType *ET);
250
251  static void genTypeInstance(Context &C, const RSExportType *ET);
252
253  static void genFieldPackerInstance(Context &C, const RSExportType *ET);
254
255  bool genTypeClass(Context &C, const RSExportRecordType *ERT,
256                    std::string &ErrorMsg);
257  void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
258  void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
259  void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
260  void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
261  void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
262  void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
263  void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
264  void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
265  void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
266  void genTypeClassResize(Context &C);
267
268  void genBuildElement(Context &C, const char *ElementBuilderName,
269                       const RSExportRecordType *ERT,
270                       const char *RenderScriptVar, bool IsInline);
271  void genAddElementToElementBuilder(Context &C, const RSExportType *ERT,
272                                     const std::string &VarName,
273                                     const char *ElementBuilderName,
274                                     const char *RenderScriptVar,
275                                     unsigned ArraySize);
276  void genAddPaddingToElementBuiler(Context &C, int PaddingSize,
277                                    const char *ElementBuilderName,
278                                    const char *RenderScriptVar);
279
280  bool genCreateFieldPacker(Context &C, const RSExportType *T,
281                            const char *FieldPackerName);
282  void genPackVarOfType(Context &C, const RSExportType *T, const char *VarName,
283                        const char *FieldPackerName);
284  void genAllocateVarOfType(Context &C, const RSExportType *T,
285                            const std::string &VarName);
286  void genNewItemBufferIfNull(Context &C, const char *Index);
287  void genNewItemBufferPackerIfNull(Context &C);
288
289public:
290  explicit RSReflectionJava(const RSContext *Context,
291                            std::vector<std::string> *GeneratedFileNames)
292      : mRSContext(Context), mLastError(""),
293        mGeneratedFileNames(GeneratedFileNames) {
294    slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
295  }
296
297  bool reflect(const std::string &OutputPathBase,
298               const std::string &OutputPackageName,
299               const std::string &RSPackageName,
300               const std::string &InputFileName,
301               const std::string &OutputBCFileName, bool EmbedBitcodeInJava);
302
303  inline const char *getLastError() const {
304    if (mLastError.empty())
305      return NULL;
306    else
307      return mLastError.c_str();
308  }
309}; // class RSReflectionJava
310
311} // namespace slang
312
313#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
314