blob: 2750af6d24861d7bb16572d8651b517c7243a54e [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#ifndef _SLANG_COMPILER_RS_REFLECTION_H
2#define _SLANG_COMPILER_RS_REFLECTION_H
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003
Shih-wei Liao462aefd2010-06-04 15:32:04 -07004#include <map>
5#include <vector>
6#include <string>
7#include <cassert>
8#include <fstream>
9#include <iostream>
10
zonr6315f762010-10-05 15:35:14 +080011#include "llvm/ADT/StringExtras.h"
12
13#include "slang_rs_export_type.h"
14
Shih-wei Liao462aefd2010-06-04 15:32:04 -070015namespace slang {
16
zonr6315f762010-10-05 15:35:14 +080017 class RSContext;
18 class RSExportVar;
19 class RSExportFunc;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020
21class RSReflection {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022 private:
23 const RSContext *mRSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070024
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070025 std::string mLastError;
26 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070027
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070028 class Context {
29 private:
30 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080031
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070032 static const char *const Import[];
Shih-wei Liao462aefd2010-06-04 15:32:04 -070033
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070034 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070035
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070036 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070037
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070038 std::string mPackageName;
39 std::string mResourceId;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070040
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070041 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070042
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070044
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070046
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070047 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070048
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070049 int mNextExportVarSlot;
50 int mNextExportFuncSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070051
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070052 // A mapping from a field in a record type to its index in the rsType
53 // instance. Only used when generates TypeClass (ScriptField_*).
54 typedef std::map<const RSExportRecordType::Field*, unsigned> FieldIndexMapTy;
55 FieldIndexMapTy mFieldIndexMap;
56 // Field index of current processing TypeClass.
57 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070058
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070059 inline void clear() {
60 mClassName = "";
61 mIndent = "";
62 mPaddingFieldIndex = 1;
63 mNextExportVarSlot = 0;
64 mNextExportFuncSlot = 0;
65 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070066 }
67
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070068 public:
69 typedef enum {
70 AM_Public,
71 AM_Protected,
72 AM_Private
73 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070075 bool mUseStdout;
76 mutable std::ofstream mOF;
77
78 static const char *AccessModifierStr(AccessModifier AM);
79
80 Context(const std::string &InputRSFile,
81 const std::string &PackageName,
82 const std::string &ResourceId,
83 bool UseStdout)
84 : mVerbose(true),
85 mInputRSFile(InputRSFile),
86 mPackageName(PackageName),
87 mResourceId(ResourceId),
88 mLicenseNote(ApacheLicenseNote),
89 mUseStdout(UseStdout) {
90 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +080091 resetFieldIndex();
92 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070093 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070094 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070095
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070096 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +080097 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070098 }
99 inline std::ostream &indent() const {
100 out() << mIndent;
101 return out();
102 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700103
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700104 inline void incIndentLevel() {
105 mIndent.append(4, ' ');
106 return;
107 }
108
109 inline void decIndentLevel() {
110 assert(getIndentLevel() > 0 && "No indent");
111 mIndent.erase(0, 4);
112 return;
113 }
114
Zonr Chang92b344a2010-10-05 20:39:03 +0800115 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700116
Zonr Chang92b344a2010-10-05 20:39:03 +0800117 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700118
Zonr Chang92b344a2010-10-05 20:39:03 +0800119 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700120
121 // Will remove later due to field name information is not necessary for
122 // C-reflect-to-Java
123 inline std::string createPaddingField() {
124 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
125 }
126
127 inline void setLicenseNote(const std::string &LicenseNote) {
128 mLicenseNote = LicenseNote;
129 }
130
131 bool startClass(AccessModifier AM,
132 bool IsStatic,
133 const std::string &ClassName,
134 const char *SuperClassName,
135 std::string &ErrorMsg);
136 void endClass();
137
138 void startFunction(AccessModifier AM,
139 bool IsStatic,
140 const char *ReturnType,
141 const std::string &FunctionName,
142 int Argc, ...);
143
144 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
145 void startFunction(AccessModifier AM,
146 bool IsStatic,
147 const char *ReturnType,
148 const std::string &FunctionName,
149 const ArgTy &Args);
150 void endFunction();
151
152 void startBlock(bool ShouldIndent = false);
153 void endBlock();
154
155 inline const std::string &getPackageName() const { return mPackageName; }
156 inline const std::string &getClassName() const { return mClassName; }
157 inline const std::string &getResourceId() const { return mResourceId; }
158
159 void startTypeClass(const std::string &ClassName);
160 void endTypeClass();
161
Zonr Chang92b344a2010-10-05 20:39:03 +0800162 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700163
Zonr Chang92b344a2010-10-05 20:39:03 +0800164 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700165
166 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
167 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
168 "Nested structure never occurs in C language.");
169 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
170 }
171
172 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
173 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
174 assert((I != mFieldIndexMap.end()) &&
175 "Requesting field is out of scope.");
176 return I->second;
177 }
178
Zonr Chang92b344a2010-10-05 20:39:03 +0800179 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700180 };
181
182 bool openScriptFile(Context &C,
183 const std::string &ClassName,
184 std::string &ErrorMsg);
185 bool genScriptClass(Context &C,
186 const std::string &ClassName,
187 std::string &ErrorMsg);
188 void genScriptClassConstructor(Context &C);
189
190 void genInitBoolExportVariable(Context &C,
191 const std::string &VarName,
192 const clang::APValue &Val);
193 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800194 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700195 const clang::APValue &Val);
196 void genInitExportVariable(Context &C,
197 const RSExportType *ET,
198 const std::string &VarName,
199 const clang::APValue &Val);
200 void genExportVariable(Context &C, const RSExportVar *EV);
201 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
202 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
203 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang92b344a2010-10-05 20:39:03 +0800204 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
206 void genGetExportVariable(Context &C,
207 const std::string &TypeName,
208 const std::string &VarName);
209
210 void genExportFunction(Context &C,
211 const RSExportFunc *EF);
212
213 bool genTypeClass(Context &C,
214 const RSExportRecordType *ERT,
215 std::string &ErrorMsg);
216 bool genTypeItemClass(Context &C,
217 const RSExportRecordType *ERT,
218 std::string &ErrorMsg);
Zonr Chang92b344a2010-10-05 20:39:03 +0800219 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
220 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
221 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700222 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
223 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
224 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
225 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
226
227 void genBuildElement(Context &C,
228 const RSExportRecordType *ERT,
229 const char *RenderScriptVar);
230 void genAddElementToElementBuilder(Context &C,
231 const RSExportType *ERT,
232 const std::string &VarName,
233 const char *ElementBuilderName,
234 const char *RenderScriptVar);
235 void genAddPaddingToElementBuiler(Context &C,
236 int PaddingSize,
237 const char *ElementBuilderName,
238 const char *RenderScriptVar);
239
240 bool genCreateFieldPacker(Context &C,
241 const RSExportType *T,
242 const char *FieldPackerName);
243 void genPackVarOfType(Context &C,
244 const RSExportType *T,
245 const char *VarName,
246 const char *FieldPackerName);
247 void genNewItemBufferIfNull(Context &C, const char *Index);
248 void genNewItemBufferPackerIfNull(Context &C);
249
250 public:
zonr6315f762010-10-05 15:35:14 +0800251 explicit RSReflection(const RSContext *Context)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700252 : mRSContext(Context),
253 mLastError("") {
254 return;
255 }
256
257 bool reflect(const char *OutputPackageName,
258 const std::string &InputFileName,
259 const std::string &OutputBCFileName);
260
261 inline const char *getLastError() const {
262 if (mLastError.empty())
263 return NULL;
264 else
265 return mLastError.c_str();
266 }
267}; // class RSReflection
268
269} // namespace slang
270
zonr6315f762010-10-05 15:35:14 +0800271#endif // _SLANG_COMPILER_RS_REFLECTION_H