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