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