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