slang_rs_reflection.h revision efcff1017f5f1e120a8ffb67125e412343479f94
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
34class RSContext;
35class RSExportVar;
36class RSExportFunc;
37class RSExportForEach;
38
39class RSReflectionJava {
40private:
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  static const char *const ApacheLicenseNote;
49
50  bool mVerbose;
51
52  std::string mOutputPathBase;
53
54  std::string mInputFileName;
55
56  std::string mPackageName;
57  std::string mRSPackageName;
58  std::string mResourceId;
59  std::string mPaddingPrefix;
60
61  std::string mClassName;
62
63  std::string mLicenseNote;
64
65  bool mEmbedBitcodeInJava;
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> 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  }
90
91  bool openClassFile(const std::string &ClassName, std::string &ErrorMsg);
92
93public:
94  typedef enum {
95    AM_Public,
96    AM_Protected,
97    AM_Private,
98    AM_PublicSynchronized
99  } AccessModifier;
100
101  mutable std::ofstream mOF;
102
103  // Generated RS Elements for type-checking code.
104  std::set<std::string> mTypesToCheck;
105
106  // Generated FieldPackers for unsigned setters/validation.
107  std::set<std::string> mFieldPackerTypes;
108
109  bool addTypeNameForElement(const std::string &TypeName);
110  bool addTypeNameForFieldPacker(const std::string &TypeName);
111
112  static const char *AccessModifierStr(AccessModifier AM);
113
114  inline std::string &getInputFileName() { return mInputFileName; }
115
116  inline std::ostream &out() const { return mOF; }
117  inline std::ostream &indent() const {
118    out() << mIndent;
119    return out();
120  }
121
122  inline void incIndentLevel() { mIndent.append(4, ' '); }
123
124  inline void decIndentLevel() {
125    slangAssert(getIndentLevel() > 0 && "No indent");
126    mIndent.erase(0, 4);
127  }
128
129  inline int getIndentLevel() { return (mIndent.length() >> 2); }
130
131  inline bool getEmbedBitcodeInJava() const { return mEmbedBitcodeInJava; }
132
133  inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
134
135  inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
136  inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
137
138  // Will remove later due to field name information is not necessary for
139  // C-reflect-to-Java
140  inline std::string createPaddingField() {
141    return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
142  }
143
144  inline void setLicenseNote(const std::string &LicenseNote) {
145    mLicenseNote = LicenseNote;
146  }
147
148  bool startClass(AccessModifier AM, bool IsStatic,
149                  const std::string &ClassName, const char *SuperClassName,
150                  std::string &ErrorMsg);
151  void endClass();
152
153  void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
154                     const std::string &FunctionName, int Argc, ...);
155
156  typedef std::vector<std::pair<std::string, std::string>> ArgTy;
157  void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
158                     const std::string &FunctionName, const ArgTy &Args);
159  void endFunction();
160
161  void startBlock(bool ShouldIndent = false);
162  void endBlock();
163
164  inline const std::string &getPackageName() const { return mPackageName; }
165  inline const std::string &getRSPackageName() const { return mRSPackageName; }
166  inline const std::string &getClassName() const { return mClassName; }
167  inline const std::string &getResourceId() const { return mResourceId; }
168
169  void startTypeClass(const std::string &ClassName);
170  void endTypeClass();
171
172  inline void incFieldIndex() { mFieldIndex++; }
173
174  inline void resetFieldIndex() { mFieldIndex = 0; }
175
176  inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
177    slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
178                "Nested structure never occurs in C language.");
179    mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
180  }
181
182  inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
183    FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
184    slangAssert((I != mFieldIndexMap.end()) &&
185                "Requesting field is out of scope.");
186    return I->second;
187  }
188
189  inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
190
191private:
192  bool genScriptClass(const std::string &ClassName, std::string &ErrorMsg);
193  void genScriptClassConstructor();
194
195  void genInitBoolExportVariable(const std::string &VarName,
196                                 const clang::APValue &Val);
197  void genInitPrimitiveExportVariable(const std::string &VarName,
198                                      const clang::APValue &Val);
199  void genInitExportVariable(const RSExportType *ET, const std::string &VarName,
200                             const clang::APValue &Val);
201  void genInitValue(const clang::APValue &Val, bool asBool);
202  void genExportVariable(const RSExportVar *EV);
203  void genPrimitiveTypeExportVariable(const RSExportVar *EV);
204  void genPointerTypeExportVariable(const RSExportVar *EV);
205  void genVectorTypeExportVariable(const RSExportVar *EV);
206  void genMatrixTypeExportVariable(const RSExportVar *EV);
207  void genConstantArrayTypeExportVariable(const RSExportVar *EV);
208  void genRecordTypeExportVariable(const RSExportVar *EV);
209  void genPrivateExportVariable(const std::string &TypeName,
210                                const std::string &VarName);
211  void genSetExportVariable(const std::string &TypeName, const RSExportVar *EV);
212  void genGetExportVariable(const std::string &TypeName,
213                            const std::string &VarName);
214  void genGetFieldID(const std::string &VarName);
215
216  void genExportFunction(const RSExportFunc *EF);
217
218  void genExportForEach(const RSExportForEach *EF);
219
220  void genTypeCheck(const RSExportType *ET, const char *VarName);
221
222  void genTypeInstanceFromPointer(const RSExportType *ET);
223
224  void genTypeInstance(const RSExportType *ET);
225
226  void genFieldPackerInstance(const RSExportType *ET);
227
228  bool genTypeClass(const RSExportRecordType *ERT, std::string &ErrorMsg);
229  void genTypeItemClass(const RSExportRecordType *ERT);
230  void genTypeClassConstructor(const RSExportRecordType *ERT);
231  void genTypeClassCopyToArray(const RSExportRecordType *ERT);
232  void genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT);
233  void genTypeClassItemSetter(const RSExportRecordType *ERT);
234  void genTypeClassItemGetter(const RSExportRecordType *ERT);
235  void genTypeClassComponentSetter(const RSExportRecordType *ERT);
236  void genTypeClassComponentGetter(const RSExportRecordType *ERT);
237  void genTypeClassCopyAll(const RSExportRecordType *ERT);
238  void genTypeClassResize();
239
240  void genBuildElement(const char *ElementBuilderName,
241                       const RSExportRecordType *ERT,
242                       const char *RenderScriptVar, bool IsInline);
243  void genAddElementToElementBuilder(const RSExportType *ERT,
244                                     const std::string &VarName,
245                                     const char *ElementBuilderName,
246                                     const char *RenderScriptVar,
247                                     unsigned ArraySize);
248  void genAddPaddingToElementBuilder(int PaddingSize,
249                                     const char *ElementBuilderName,
250                                     const char *RenderScriptVar);
251
252  bool genCreateFieldPacker(const RSExportType *T, const char *FieldPackerName);
253  void genPackVarOfType(const RSExportType *T, const char *VarName,
254                        const char *FieldPackerName);
255  void genAllocateVarOfType(const RSExportType *T, const std::string &VarName);
256  void genNewItemBufferIfNull(const char *Index);
257  void genNewItemBufferPackerIfNull();
258
259public:
260  explicit RSReflectionJava(const RSContext *Context,
261                            std::vector<std::string> *GeneratedFileNames)
262      : mRSContext(Context), mLastError(""),
263        mGeneratedFileNames(GeneratedFileNames) {
264    slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
265  }
266
267  bool reflect(const std::string &OutputPathBase,
268               const std::string &OutputPackageName,
269               const std::string &RSPackageName,
270               const std::string &InputFileName,
271               const std::string &OutputBCFileName, bool EmbedBitcodeInJava);
272
273  inline const char *getLastError() const {
274    if (mLastError.empty())
275      return NULL;
276    else
277      return mLastError.c_str();
278  }
279}; // class RSReflectionJava
280
281} // namespace slang
282
283#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
284