blob: ded42b4e4242fbc671f2b60a857d4d2af7a53390 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hines0a813a32012-08-03 16:52:40 -07002 * Copyright 2010-2012, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
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
Stephen Hinese639eb52010-11-08 19:27:20 -080017#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020#include <fstream>
21#include <iostream>
Stephen Hinese639eb52010-11-08 19:27:20 -080022#include <map>
Stephen Hines48b72bf2011-06-10 15:37:27 -070023#include <set>
Stephen Hinese639eb52010-11-08 19:27:20 -080024#include <string>
25#include <vector>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070026
zonr6315f762010-10-05 15:35:14 +080027#include "llvm/ADT/StringExtras.h"
28
Stephen Hines6e6578a2011-02-07 18:05:48 -080029#include "slang_assert.h"
zonr6315f762010-10-05 15:35:14 +080030#include "slang_rs_export_type.h"
31
Shih-wei Liao462aefd2010-06-04 15:32:04 -070032namespace slang {
33
zonr6315f762010-10-05 15:35:14 +080034 class RSContext;
35 class RSExportVar;
36 class RSExportFunc;
Stephen Hines593a8942011-05-10 15:29:50 -070037 class RSExportForEach;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070038
39class RSReflection {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070040 private:
41 const RSContext *mRSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070042
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043 std::string mLastError;
Stephen Hines4cc67fc2011-01-31 16:48:57 -080044 std::vector<std::string> *mGeneratedFileNames;
45
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070046 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070048 class Context {
49 private:
50 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080051
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070052 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070054 std::string mOutputPathBase;
Zonr Chang8c6d9b22010-10-07 18:01:19 +080055
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070056 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070057
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070058 std::string mPackageName;
Stephen Hines0a813a32012-08-03 16:52:40 -070059 std::string mRSPackageName;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070060 std::string mResourceId;
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -080061 std::string mPaddingPrefix;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070062
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070063 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070064
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070065 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070066
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070069 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070070
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070071 int mNextExportVarSlot;
72 int mNextExportFuncSlot;
Stephen Hines593a8942011-05-10 15:29:50 -070073 int mNextExportForEachSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070075 // A mapping from a field in a record type to its index in the rsType
76 // instance. Only used when generates TypeClass (ScriptField_*).
Stephen Hinese639eb52010-11-08 19:27:20 -080077 typedef std::map<const RSExportRecordType::Field*, unsigned>
78 FieldIndexMapTy;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070079 FieldIndexMapTy mFieldIndexMap;
80 // Field index of current processing TypeClass.
81 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070082
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070083 inline void clear() {
84 mClassName = "";
85 mIndent = "";
86 mPaddingFieldIndex = 1;
87 mNextExportVarSlot = 0;
88 mNextExportFuncSlot = 0;
Stephen Hines593a8942011-05-10 15:29:50 -070089 mNextExportForEachSlot = 0;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070090 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070091 }
92
Zonr Chang8c6d9b22010-10-07 18:01:19 +080093 bool openClassFile(const std::string &ClassName,
94 std::string &ErrorMsg);
95
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070096 public:
97 typedef enum {
98 AM_Public,
99 AM_Protected,
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -0700100 AM_Private,
101 AM_PublicSynchronized
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700102 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700103
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700104 bool mUseStdout;
105 mutable std::ofstream mOF;
106
Stephen Hines1f6c3312012-07-03 17:23:33 -0700107 // Generated RS Elements for type-checking code.
Stephen Hines48b72bf2011-06-10 15:37:27 -0700108 std::set<std::string> mTypesToCheck;
109
Stephen Hines1f6c3312012-07-03 17:23:33 -0700110 // Generated FieldPackers for unsigned setters/validation.
111 std::set<std::string> mFieldPackerTypes;
112
113 bool addTypeNameForElement(const std::string &TypeName);
114 bool addTypeNameForFieldPacker(const std::string &TypeName);
115
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700116 static const char *AccessModifierStr(AccessModifier AM);
117
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700118 Context(const std::string &OutputPathBase,
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800119 const std::string &InputRSFile,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700120 const std::string &PackageName,
Stephen Hines0a813a32012-08-03 16:52:40 -0700121 const std::string &RSPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700122 const std::string &ResourceId,
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -0800123 const std::string &PaddingPrefix,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700124 bool UseStdout)
125 : mVerbose(true),
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700126 mOutputPathBase(OutputPathBase),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700127 mInputRSFile(InputRSFile),
128 mPackageName(PackageName),
Stephen Hines0a813a32012-08-03 16:52:40 -0700129 mRSPackageName(RSPackageName),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700130 mResourceId(ResourceId),
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -0800131 mPaddingPrefix(PaddingPrefix),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700132 mLicenseNote(ApacheLicenseNote),
133 mUseStdout(UseStdout) {
134 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +0800135 resetFieldIndex();
136 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700137 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700138 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700139
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700140 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +0800141 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700142 }
143 inline std::ostream &indent() const {
144 out() << mIndent;
145 return out();
146 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700147
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700148 inline void incIndentLevel() {
149 mIndent.append(4, ' ');
150 return;
151 }
152
153 inline void decIndentLevel() {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800154 slangAssert(getIndentLevel() > 0 && "No indent");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700155 mIndent.erase(0, 4);
156 return;
157 }
158
Zonr Chang92b344a2010-10-05 20:39:03 +0800159 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700160
Zonr Chang92b344a2010-10-05 20:39:03 +0800161 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700162
Zonr Chang92b344a2010-10-05 20:39:03 +0800163 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Stephen Hines593a8942011-05-10 15:29:50 -0700164 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700165
166 // Will remove later due to field name information is not necessary for
167 // C-reflect-to-Java
168 inline std::string createPaddingField() {
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -0800169 return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700170 }
171
172 inline void setLicenseNote(const std::string &LicenseNote) {
173 mLicenseNote = LicenseNote;
174 }
175
176 bool startClass(AccessModifier AM,
177 bool IsStatic,
178 const std::string &ClassName,
179 const char *SuperClassName,
180 std::string &ErrorMsg);
181 void endClass();
182
183 void startFunction(AccessModifier AM,
184 bool IsStatic,
185 const char *ReturnType,
186 const std::string &FunctionName,
187 int Argc, ...);
188
189 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
190 void startFunction(AccessModifier AM,
191 bool IsStatic,
192 const char *ReturnType,
193 const std::string &FunctionName,
194 const ArgTy &Args);
195 void endFunction();
196
197 void startBlock(bool ShouldIndent = false);
198 void endBlock();
199
200 inline const std::string &getPackageName() const { return mPackageName; }
Stephen Hines0a813a32012-08-03 16:52:40 -0700201 inline const std::string &getRSPackageName() const {
202 return mRSPackageName;
203 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700204 inline const std::string &getClassName() const { return mClassName; }
205 inline const std::string &getResourceId() const { return mResourceId; }
206
207 void startTypeClass(const std::string &ClassName);
208 void endTypeClass();
209
Zonr Chang92b344a2010-10-05 20:39:03 +0800210 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700211
Zonr Chang92b344a2010-10-05 20:39:03 +0800212 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700213
214 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800215 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
216 "Nested structure never occurs in C language.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700217 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
218 }
219
220 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
221 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
Stephen Hines6e6578a2011-02-07 18:05:48 -0800222 slangAssert((I != mFieldIndexMap.end()) &&
223 "Requesting field is out of scope.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700224 return I->second;
225 }
226
Zonr Chang92b344a2010-10-05 20:39:03 +0800227 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700228 };
229
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700230 bool genScriptClass(Context &C,
231 const std::string &ClassName,
232 std::string &ErrorMsg);
233 void genScriptClassConstructor(Context &C);
234
Stephen Hines5d671782012-01-31 19:32:04 -0800235 static void genInitBoolExportVariable(Context &C,
236 const std::string &VarName,
237 const clang::APValue &Val);
238 static void genInitPrimitiveExportVariable(Context &C,
239 const std::string &VarName,
240 const clang::APValue &Val);
241 static void genInitExportVariable(Context &C,
242 const RSExportType *ET,
243 const std::string &VarName,
244 const clang::APValue &Val);
245 static void genInitValue(Context &C, const clang::APValue &Val);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700246 void genExportVariable(Context &C, const RSExportVar *EV);
247 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
248 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
249 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang92b344a2010-10-05 20:39:03 +0800250 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800251 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700252 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
Stephen Hines0d26cef2012-05-01 19:23:01 -0700253 void genPrivateExportVariable(Context &C,
254 const std::string &TypeName,
255 const std::string &VarName);
256 void genSetExportVariable(Context &C,
257 const std::string &TypeName,
258 const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700259 void genGetExportVariable(Context &C,
260 const std::string &TypeName,
261 const std::string &VarName);
Stephen Hines28d60bc2012-10-15 15:54:16 -0700262 void genGetFieldID(Context &C,
263 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700264
265 void genExportFunction(Context &C,
266 const RSExportFunc *EF);
267
Stephen Hines593a8942011-05-10 15:29:50 -0700268 void genExportForEach(Context &C,
269 const RSExportForEach *EF);
270
Stephen Hines48b72bf2011-06-10 15:37:27 -0700271 static void genTypeCheck(Context &C,
272 const RSExportType *ET,
273 const char *VarName);
274
Stephen Hinesa6b54142012-04-09 18:25:08 -0700275 static void genTypeInstanceFromPointer(Context &C,
276 const RSExportType *ET);
277
Stephen Hines48b72bf2011-06-10 15:37:27 -0700278 static void genTypeInstance(Context &C,
279 const RSExportType *ET);
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700280
Stephen Hines1f6c3312012-07-03 17:23:33 -0700281 static void genFieldPackerInstance(Context &C,
282 const RSExportType *ET);
283
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700284 bool genTypeClass(Context &C,
285 const RSExportRecordType *ERT,
286 std::string &ErrorMsg);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800287 void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800288 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
289 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -0700290 void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800291 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700292 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
293 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
294 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
295 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
Zonr Changd42a4292010-10-17 02:38:43 +0800296 void genTypeClassResize(Context &C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700297
298 void genBuildElement(Context &C,
Zonr Chang89273bd2010-10-14 20:57:38 +0800299 const char *ElementBuilderName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700300 const RSExportRecordType *ERT,
Zonr Chang89273bd2010-10-14 20:57:38 +0800301 const char *RenderScriptVar,
302 bool IsInline);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700303 void genAddElementToElementBuilder(Context &C,
304 const RSExportType *ERT,
305 const std::string &VarName,
306 const char *ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +0800307 const char *RenderScriptVar,
308 unsigned ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700309 void genAddPaddingToElementBuiler(Context &C,
310 int PaddingSize,
311 const char *ElementBuilderName,
312 const char *RenderScriptVar);
313
314 bool genCreateFieldPacker(Context &C,
315 const RSExportType *T,
316 const char *FieldPackerName);
317 void genPackVarOfType(Context &C,
318 const RSExportType *T,
319 const char *VarName,
320 const char *FieldPackerName);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800321 void genAllocateVarOfType(Context &C,
322 const RSExportType *T,
323 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700324 void genNewItemBufferIfNull(Context &C, const char *Index);
325 void genNewItemBufferPackerIfNull(Context &C);
326
327 public:
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800328 explicit RSReflection(const RSContext *Context,
329 std::vector<std::string> *GeneratedFileNames)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700330 : mRSContext(Context),
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800331 mLastError(""),
332 mGeneratedFileNames(GeneratedFileNames) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800333 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700334 return;
335 }
336
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700337 bool reflect(const std::string &OutputPathBase,
338 const std::string &OutputPackageName,
Stephen Hines0a813a32012-08-03 16:52:40 -0700339 const std::string &RSPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700340 const std::string &InputFileName,
341 const std::string &OutputBCFileName);
342
343 inline const char *getLastError() const {
344 if (mLastError.empty())
345 return NULL;
346 else
347 return mLastError.c_str();
348 }
349}; // class RSReflection
350
351} // namespace slang
352
Stephen Hinese639eb52010-11-08 19:27:20 -0800353#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT