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