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