slang_rs_reflection.h revision 4c8b659edc8dca50ffb9c172258412fc1e02b80d
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
34  class RSContext;
35  class RSExportVar;
36  class RSExportFunc;
37  class RSExportForEach;
38
39class RSReflection {
40 private:
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      return;
95    }
96
97    bool openClassFile(const std::string &ClassName,
98                       std::string &ErrorMsg);
99
100   public:
101    typedef enum {
102      AM_Public,
103      AM_Protected,
104      AM_Private,
105      AM_PublicSynchronized
106    } AccessModifier;
107
108    mutable std::ofstream mOF;
109
110    // Generated RS Elements for type-checking code.
111    std::set<std::string> mTypesToCheck;
112
113    // Generated FieldPackers for unsigned setters/validation.
114    std::set<std::string> mFieldPackerTypes;
115
116    bool addTypeNameForElement(const std::string &TypeName);
117    bool addTypeNameForFieldPacker(const std::string &TypeName);
118
119    static const char *AccessModifierStr(AccessModifier AM);
120
121    Context(const std::string &OutputPathBase,
122            const std::string &InputRSFile,
123            const std::string &PackageName,
124            const std::string &RSPackageName,
125            const std::string &ResourceId,
126            const std::string &PaddingPrefix,
127            bool UseStdout,
128            bool EmbedBitcodeInJava)
129        : mVerbose(true),
130          mOutputPathBase(OutputPathBase),
131          mInputRSFile(InputRSFile),
132          mPackageName(PackageName),
133          mRSPackageName(RSPackageName),
134          mResourceId(ResourceId),
135          mPaddingPrefix(PaddingPrefix),
136          mLicenseNote(ApacheLicenseNote),
137          mUseStdout(UseStdout),
138          mEmbedBitcodeInJava(EmbedBitcodeInJava) {
139      clear();
140      resetFieldIndex();
141      clearFieldIndexMap();
142      return;
143    }
144
145    inline std::string &getInputRSFile() {
146      return mInputRSFile;
147    }
148
149    inline std::ostream &out() const {
150      return ((mUseStdout) ? std::cout : mOF);
151    }
152    inline std::ostream &indent() const {
153      out() << mIndent;
154      return out();
155    }
156
157    inline void incIndentLevel() {
158      mIndent.append(4, ' ');
159      return;
160    }
161
162    inline void decIndentLevel() {
163      slangAssert(getIndentLevel() > 0 && "No indent");
164      mIndent.erase(0, 4);
165      return;
166    }
167
168    inline int getIndentLevel() { return (mIndent.length() >> 2); }
169
170    inline bool getEmbedBitcodeInJava() const { return mEmbedBitcodeInJava; }
171
172    inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
173
174    inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
175    inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
176
177    // Will remove later due to field name information is not necessary for
178    // C-reflect-to-Java
179    inline std::string createPaddingField() {
180      return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
181    }
182
183    inline void setLicenseNote(const std::string &LicenseNote) {
184      mLicenseNote = LicenseNote;
185    }
186
187    bool startClass(AccessModifier AM,
188                    bool IsStatic,
189                    const std::string &ClassName,
190                    const char *SuperClassName,
191                    std::string &ErrorMsg);
192    void endClass();
193
194    void startFunction(AccessModifier AM,
195                       bool IsStatic,
196                       const char *ReturnType,
197                       const std::string &FunctionName,
198                       int Argc, ...);
199
200    typedef std::vector<std::pair<std::string, std::string> > ArgTy;
201    void startFunction(AccessModifier AM,
202                       bool IsStatic,
203                       const char *ReturnType,
204                       const std::string &FunctionName,
205                       const ArgTy &Args);
206    void endFunction();
207
208    void startBlock(bool ShouldIndent = false);
209    void endBlock();
210
211    inline const std::string &getPackageName() const { return mPackageName; }
212    inline const std::string &getRSPackageName() const {
213      return mRSPackageName;
214    }
215    inline const std::string &getClassName() const { return mClassName; }
216    inline const std::string &getResourceId() const { return mResourceId; }
217
218    void startTypeClass(const std::string &ClassName);
219    void endTypeClass();
220
221    inline void incFieldIndex() { mFieldIndex++; }
222
223    inline void resetFieldIndex() { mFieldIndex = 0; }
224
225    inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
226      slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
227                  "Nested structure never occurs in C language.");
228      mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
229    }
230
231    inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
232      FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
233      slangAssert((I != mFieldIndexMap.end()) &&
234                  "Requesting field is out of scope.");
235      return I->second;
236    }
237
238    inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
239  };
240
241  bool genScriptClass(Context &C,
242                      const std::string &ClassName,
243                      std::string &ErrorMsg);
244  void genScriptClassConstructor(Context &C);
245
246  static void genInitBoolExportVariable(Context &C,
247                                        const std::string &VarName,
248                                        const clang::APValue &Val);
249  static void genInitPrimitiveExportVariable(Context &C,
250                                             const std::string &VarName,
251                                             const clang::APValue &Val);
252  static void genInitExportVariable(Context &C,
253                                    const RSExportType *ET,
254                                    const std::string &VarName,
255                                    const clang::APValue &Val);
256  void genExportVariable(Context &C, const RSExportVar *EV);
257  void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
258  void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
259  void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
260  void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
261  void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
262  void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
263  void genPrivateExportVariable(Context &C,
264                                const std::string &TypeName,
265                                const std::string &VarName);
266  void genSetExportVariable(Context &C,
267                            const std::string &TypeName,
268                            const RSExportVar *EV);
269  void genGetExportVariable(Context &C,
270                            const std::string &TypeName,
271                            const std::string &VarName);
272  void genGetFieldID(Context &C,
273                     const std::string &VarName);
274
275  void genExportFunction(Context &C,
276                         const RSExportFunc *EF);
277
278  void genExportForEach(Context &C,
279                        const RSExportForEach *EF);
280
281  static void genTypeCheck(Context &C,
282                           const RSExportType *ET,
283                           const char *VarName);
284
285  static void genTypeInstanceFromPointer(Context &C,
286                                         const RSExportType *ET);
287
288  static void genTypeInstance(Context &C,
289                              const RSExportType *ET);
290
291  static void genFieldPackerInstance(Context &C,
292                                     const RSExportType *ET);
293
294  bool genTypeClass(Context &C,
295                    const RSExportRecordType *ERT,
296                    std::string &ErrorMsg);
297  void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
298  void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
299  void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
300  void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
301  void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
302  void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
303  void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
304  void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
305  void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
306  void genTypeClassResize(Context &C);
307
308  void genBuildElement(Context &C,
309                       const char *ElementBuilderName,
310                       const RSExportRecordType *ERT,
311                       const char *RenderScriptVar,
312                       bool IsInline);
313  void genAddElementToElementBuilder(Context &C,
314                                     const RSExportType *ERT,
315                                     const std::string &VarName,
316                                     const char *ElementBuilderName,
317                                     const char *RenderScriptVar,
318                                     unsigned ArraySize);
319  void genAddPaddingToElementBuiler(Context &C,
320                                    int PaddingSize,
321                                    const char *ElementBuilderName,
322                                    const char *RenderScriptVar);
323
324  bool genCreateFieldPacker(Context &C,
325                            const RSExportType *T,
326                            const char *FieldPackerName);
327  void genPackVarOfType(Context &C,
328                        const RSExportType *T,
329                        const char *VarName,
330                        const char *FieldPackerName);
331  void genAllocateVarOfType(Context &C,
332                            const RSExportType *T,
333                            const std::string &VarName);
334  void genNewItemBufferIfNull(Context &C, const char *Index);
335  void genNewItemBufferPackerIfNull(Context &C);
336
337 public:
338  explicit RSReflection(const RSContext *Context,
339      std::vector<std::string> *GeneratedFileNames)
340      : mRSContext(Context),
341        mLastError(""),
342        mGeneratedFileNames(GeneratedFileNames) {
343    slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
344    return;
345  }
346
347  bool reflect(const std::string &OutputPathBase,
348               const std::string &OutputPackageName,
349               const std::string &RSPackageName,
350               const std::string &InputFileName,
351               const std::string &OutputBCFileName,
352               bool EmbedBitcodeInJava);
353
354  inline const char *getLastError() const {
355    if (mLastError.empty())
356      return NULL;
357    else
358      return mLastError.c_str();
359  }
360};  // class RSReflection
361
362}   // namespace slang
363
364#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
365