slang_rs_reflection.cpp revision 050eb857325d6cd35f23fae6c82200aff5a9bcc1
1#include "slang_rs_reflection.h"
2
3#include <utility>
4#include <cstdarg>
5#include <cctype>
6#include <sys/stat.h>
7
8#include "llvm/ADT/APFloat.h"
9
10#include "slang_rs_context.h"
11#include "slang_rs_export_var.h"
12#include "slang_rs_export_func.h"
13#include "slang_rs_reflect_utils.h"
14
15#define RS_SCRIPT_CLASS_NAME_PREFIX      "ScriptC_"
16#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
17
18#define RS_TYPE_CLASS_NAME_PREFIX        "ScriptField_"
19#define RS_TYPE_CLASS_SUPER_CLASS_NAME   "android.renderscript.Script.FieldBase"
20
21#define RS_TYPE_ITEM_CLASS_NAME          "Item"
22
23#define RS_TYPE_ITEM_BUFFER_NAME         "mItemArray"
24#define RS_TYPE_ITEM_BUFFER_PACKER_NAME  "mIOBuffer"
25
26#define RS_EXPORT_VAR_INDEX_PREFIX       "mExportVarIdx_"
27#define RS_EXPORT_VAR_PREFIX             "mExportVar_"
28
29#define RS_EXPORT_FUNC_INDEX_PREFIX      "mExportFuncIdx_"
30
31#define RS_EXPORT_VAR_ALLOCATION_PREFIX  "mAlloction_"
32#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
33
34using namespace slang;
35
36// Some utility function using internal in RSReflection
37static bool GetClassNameFromFileName(const std::string &FileName,
38                                     std::string &ClassName) {
39  ClassName.clear();
40
41  if (FileName.empty() || (FileName == "-"))
42    return true;
43
44  ClassName =
45      RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str());
46
47  return true;
48}
49
50static const char *GetPrimitiveTypeName(const RSExportPrimitiveType *EPT) {
51  static const char *PrimitiveTypeJavaNameMap[] = {
52    "",         // RSExportPrimitiveType::DataTypeFloat16
53    "float",    // RSExportPrimitiveType::DataTypeFloat32
54    "double",   // RSExportPrimitiveType::DataTypeFloat64
55    "byte",     // RSExportPrimitiveType::DataTypeSigned8
56    "short",    // RSExportPrimitiveType::DataTypeSigned16
57    "int",      // RSExportPrimitiveType::DataTypeSigned32
58    "long",     // RSExportPrimitiveType::DataTypeSigned64
59    "short",    // RSExportPrimitiveType::DataTypeUnsigned8
60    "int",      // RSExportPrimitiveType::DataTypeUnsigned16
61    "long",     // RSExportPrimitiveType::DataTypeUnsigned32
62    "long",     // RSExportPrimitiveType::DataTypeUnsigned64
63    "boolean",  // RSExportPrimitiveType::DataTypeBoolean
64
65    "int",      // RSExportPrimitiveType::DataTypeUnsigned565
66    "int",      // RSExportPrimitiveType::DataTypeUnsigned5551
67    "int",      // RSExportPrimitiveType::DataTypeUnsigned4444
68
69    "",     // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
70    "",     // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
71    "",     // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
72
73    "Element",      // RSExportPrimitiveType::DataTypeRSElement
74    "Type",         // RSExportPrimitiveType::DataTypeRSType
75    "Allocation",   // RSExportPrimitiveType::DataTypeRSAllocation
76    "Sampler",      // RSExportPrimitiveType::DataTypeRSSampler
77    "Script",       // RSExportPrimitiveType::DataTypeRSScript
78    "Mesh",         // RSExportPrimitiveType::DataTypeRSMesh
79    "ProgramFragment",  // RSExportPrimitiveType::DataTypeRSProgramFragment
80    "ProgramVertex",    // RSExportPrimitiveType::DataTypeRSProgramVertex
81    "ProgramRaster",    // RSExportPrimitiveType::DataTypeRSProgramRaster
82    "ProgramStore",     // RSExportPrimitiveType::DataTypeRSProgramStore
83    "Font",     // RSExportPrimitiveType::DataTypeRSFont
84  };
85  unsigned TypeId = EPT->getType();
86
87  if (TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) {
88    return PrimitiveTypeJavaNameMap[ EPT->getType() ];
89  }
90
91  assert(false && "GetPrimitiveTypeName : Unknown primitive data type");
92  return NULL;
93}
94
95static const char *GetVectorTypeName(const RSExportVectorType *EVT) {
96  static const char *VectorTypeJavaNameMap[][3] = {
97    /* 0 */ { "Byte2",  "Byte3",    "Byte4" },
98    /* 1 */ { "Short2", "Short3",   "Short4" },
99    /* 2 */ { "Int2",   "Int3",     "Int4" },
100    /* 3 */ { "Long2",  "Long3",    "Long4" },
101    /* 4 */ { "Float2", "Float3",   "Float4" },
102  };
103
104  const char **BaseElement = NULL;
105
106  switch (EVT->getType()) {
107    case RSExportPrimitiveType::DataTypeSigned8:
108    case RSExportPrimitiveType::DataTypeBoolean: {
109      BaseElement = VectorTypeJavaNameMap[0];
110      break;
111    }
112    case RSExportPrimitiveType::DataTypeSigned16:
113    case RSExportPrimitiveType::DataTypeUnsigned8: {
114      BaseElement = VectorTypeJavaNameMap[1];
115      break;
116    }
117    case RSExportPrimitiveType::DataTypeSigned32:
118    case RSExportPrimitiveType::DataTypeUnsigned16: {
119      BaseElement = VectorTypeJavaNameMap[2];
120      break;
121    }
122    case RSExportPrimitiveType::DataTypeSigned64:
123    case RSExportPrimitiveType::DataTypeUnsigned32: {
124      BaseElement = VectorTypeJavaNameMap[3];
125      break;
126    }
127    case RSExportPrimitiveType::DataTypeFloat32: {
128      BaseElement = VectorTypeJavaNameMap[4];
129      break;
130    }
131    default: {
132      assert(false && "RSReflection::genElementTypeName : Unsupported vector "
133                      "element data type");
134      break;
135    }
136  }
137
138  assert((EVT->getNumElement() > 1) &&
139         (EVT->getNumElement() <= 4) &&
140         "Number of element in vector type is invalid");
141
142  return BaseElement[EVT->getNumElement() - 2];
143}
144
145static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
146  static const char *MatrixTypeJavaNameMap[] = {
147    /* 2x2 */ "Matrix2f",
148    /* 3x3 */ "Matrix3f",
149    /* 4x4 */ "Matrix4f",
150  };
151  unsigned Dim = EMT->getDim();
152
153  if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*)))
154    return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ];
155
156  assert(false && "GetMatrixTypeName : Unsupported matrix dimension");
157  return NULL;
158}
159
160static const char *GetVectorAccessor(int Index) {
161  static const char *VectorAccessorMap[] = {
162    /* 0 */ "x",
163    /* 1 */ "y",
164    /* 2 */ "z",
165    /* 3 */ "w",
166  };
167
168  assert((Index >= 0) &&
169         (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
170         "Out-of-bound index to access vector member");
171
172  return VectorAccessorMap[Index];
173}
174
175static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
176  static const char *PrimitiveTypePackerAPINameMap[] = {
177    "",         // RSExportPrimitiveType::DataTypeFloat16
178    "addF32",   // RSExportPrimitiveType::DataTypeFloat32
179    "addF64",   // RSExportPrimitiveType::DataTypeFloat64
180    "addI8",    // RSExportPrimitiveType::DataTypeSigned8
181    "addI16",   // RSExportPrimitiveType::DataTypeSigned16
182    "addI32",   // RSExportPrimitiveType::DataTypeSigned32
183    "addI64",   // RSExportPrimitiveType::DataTypeSigned64
184    "addU8",    // RSExportPrimitiveType::DataTypeUnsigned8
185    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned16
186    "addU32",   // RSExportPrimitiveType::DataTypeUnsigned32
187    "addU64",   // RSExportPrimitiveType::DataTypeUnsigned64
188    "addBoolean",  // RSExportPrimitiveType::DataTypeBoolean
189
190    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned565
191    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned5551
192    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned4444
193
194    "addObj",   // RSExportPrimitiveType::DataTypeRSMatrix2x2
195    "addObj",   // RSExportPrimitiveType::DataTypeRSMatrix3x3
196    "addObj",   // RSExportPrimitiveType::DataTypeRSMatrix4x4
197
198    "addObj",   // RSExportPrimitiveType::DataTypeRSElement
199    "addObj",   // RSExportPrimitiveType::DataTypeRSType
200    "addObj",   // RSExportPrimitiveType::DataTypeRSAllocation
201    "addObj",   // RSExportPrimitiveType::DataTypeRSSampler
202    "addObj",   // RSExportPrimitiveType::DataTypeRSScript
203    "addObj",   // RSExportPrimitiveType::DataTypeRSMesh
204    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramFragment
205    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramVertex
206    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramRaster
207    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramStore
208    "addObj",   // RSExportPrimitiveType::DataTypeRSFont
209  };
210  unsigned TypeId = EPT->getType();
211
212  if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))
213    return PrimitiveTypePackerAPINameMap[ EPT->getType() ];
214
215  assert(false && "GetPackerAPIName : Unknown primitive data type");
216  return NULL;
217}
218
219static std::string GetTypeName(const RSExportType *ET) {
220  switch (ET->getClass()) {
221    case RSExportType::ExportClassPrimitive: {
222      return GetPrimitiveTypeName(
223                static_cast<const RSExportPrimitiveType*>(ET));
224    }
225    case RSExportType::ExportClassPointer: {
226      const RSExportType *PointeeType =
227          static_cast<const RSExportPointerType*>(ET)->getPointeeType();
228
229      if (PointeeType->getClass() != RSExportType::ExportClassRecord)
230        return "Allocation";
231      else
232        return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName();
233    }
234    case RSExportType::ExportClassVector: {
235      return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET));
236    }
237    case RSExportType::ExportClassMatrix: {
238      return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
239    }
240    case RSExportType::ExportClassConstantArray: {
241      const RSExportConstantArrayType* CAT =
242          static_cast<const RSExportConstantArrayType*>(ET);
243      std::string ElementTypeName = GetTypeName(CAT->getElementType());
244      ElementTypeName.append("[]");
245      return ElementTypeName;
246    }
247    case RSExportType::ExportClassRecord: {
248      return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() +
249                 "."RS_TYPE_ITEM_CLASS_NAME;
250    }
251    default: {
252      assert(false && "Unknown class of type");
253    }
254  }
255
256  return "";
257}
258
259static const char *GetTypeNullValue(const RSExportType *ET) {
260  switch (ET->getClass()) {
261    case RSExportType::ExportClassPrimitive: {
262      const RSExportPrimitiveType *EPT =
263          static_cast<const RSExportPrimitiveType*>(ET);
264      if (EPT->isRSObjectType())
265        return "null";
266      else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean)
267        return "false";
268      else
269        return "0";
270      break;
271    }
272    case RSExportType::ExportClassPointer:
273    case RSExportType::ExportClassVector:
274    case RSExportType::ExportClassMatrix:
275    case RSExportType::ExportClassConstantArray:
276    case RSExportType::ExportClassRecord: {
277      return "null";
278      break;
279    }
280    default: {
281      assert(false && "Unknown class of type");
282    }
283  }
284  return "";
285}
286
287static const char *GetBuiltinElementConstruct(const RSExportType *ET) {
288  if (ET->getClass() == RSExportType::ExportClassPrimitive) {
289    const RSExportPrimitiveType *EPT =
290        static_cast<const RSExportPrimitiveType*>(ET);
291    if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
292      static const char *PrimitiveBuiltinElementConstructMap[] = {
293        NULL,   // RSExportPrimitiveType::DataTypeFloat16
294        "F32",  // RSExportPrimitiveType::DataTypeFloat32
295        "F64",  // RSExportPrimitiveType::DataTypeFloat64
296        "I8",   // RSExportPrimitiveType::DataTypeSigned8
297        NULL,   // RSExportPrimitiveType::DataTypeSigned16
298        "I32",  // RSExportPrimitiveType::DataTypeSigned32
299        "I64",  // RSExportPrimitiveType::DataTypeSigned64
300        "U8",   // RSExportPrimitiveType::DataTypeUnsigned8
301        NULL,   // RSExportPrimitiveType::DataTypeUnsigned16
302        "U32",  // RSExportPrimitiveType::DataTypeUnsigned32
303        NULL,   // RSExportPrimitiveType::DataTypeUnsigned64
304        "BOOLEAN",  // RSExportPrimitiveType::DataTypeBoolean
305
306        NULL,   // RSExportPrimitiveType::DataTypeUnsigned565
307        NULL,   // RSExportPrimitiveType::DataTypeUnsigned5551
308        NULL,   // RSExportPrimitiveType::DataTypeUnsigned4444
309
310        NULL,   // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
311        NULL,   // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
312        NULL,   // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
313
314        "ELEMENT",      // RSExportPrimitiveType::DataTypeRSElement
315        "TYPE",         // RSExportPrimitiveType::DataTypeRSType
316        "ALLOCATION",   // RSExportPrimitiveType::DataTypeRSAllocation
317        "SAMPLER",      // RSExportPrimitiveType::DataTypeRSSampler
318        "SCRIPT",       // RSExportPrimitiveType::DataTypeRSScript
319        "MESH",         // RSExportPrimitiveType::DataTypeRSMesh
320        "PROGRAM_FRAGMENT",  // RSExportPrimitiveType::DataTypeRSProgramFragment
321        "PROGRAM_VERTEX",    // RSExportPrimitiveType::DataTypeRSProgramVertex
322        "PROGRAM_RASTER",    // RSExportPrimitiveType::DataTypeRSProgramRaster
323        "PROGRAM_STORE",     // RSExportPrimitiveType::DataTypeRSProgramStore
324        "FONT",       // RSExportPrimitiveType::DataTypeRSFont
325      };
326      unsigned TypeId = EPT->getType();
327
328      if (TypeId <
329          (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*)))
330        return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
331    } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
332      if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
333        return "A_8";
334    } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
335      if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
336        return "RGB_565";
337      else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
338        return "RGB_888";
339    } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
340      if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
341        return "RGBA_5551";
342      else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
343        return "RGBA_4444";
344      else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
345        return "RGBA_8888";
346    }
347  } else if (ET->getClass() == RSExportType::ExportClassVector) {
348    const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET);
349    if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) {
350      if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
351        if (EVT->getNumElement() == 2)
352          return "F32_2";
353        else if (EVT->getNumElement() == 3)
354          return "F32_3";
355        else if (EVT->getNumElement() == 4)
356          return "F32_4";
357      } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
358        if (EVT->getNumElement() == 4)
359          return "U8_4";
360      }
361    }
362  } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
363    const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
364    switch (EMT->getDim()) {
365      case 2: {
366        return "MATRIX_2X2";
367        break;
368      }
369      case 3: {
370        return "MATRIX_3X3";
371        break;
372      }
373      case 4: {
374        return "MATRIX_4X4";
375        break;
376      }
377      default: {
378        assert(false && "Unsupported dimension of matrix");
379      }
380    }
381  } else if (ET->getClass() == RSExportType::ExportClassPointer) {
382    // Treat pointer type variable as unsigned int
383    // TODO(zonr): this is target dependent
384    return "USER_I32";
385  }
386
387  return NULL;
388}
389
390static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) {
391  static const char *ElementDataKindNameMap[] = {
392    "Element.DataKind.USER",        // RSExportPrimitiveType::DataKindUser
393    "Element.DataKind.PIXEL_L",     // RSExportPrimitiveType::DataKindPixelL
394    "Element.DataKind.PIXEL_A",     // RSExportPrimitiveType::DataKindPixelA
395    "Element.DataKind.PIXEL_LA",    // RSExportPrimitiveType::DataKindPixelLA
396    "Element.DataKind.PIXEL_RGB",   // RSExportPrimitiveType::DataKindPixelRGB
397    "Element.DataKind.PIXEL_RGBA",  // RSExportPrimitiveType::DataKindPixelRGBA
398  };
399
400  if (static_cast<unsigned>(DK) <
401      (sizeof(ElementDataKindNameMap) / sizeof(const char*)))
402    return ElementDataKindNameMap[ DK ];
403  else
404    return NULL;
405}
406
407static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) {
408  static const char *ElementDataTypeNameMap[] = {
409    NULL,                           // RSExportPrimitiveType::DataTypeFloat16
410    "Element.DataType.FLOAT_32",    // RSExportPrimitiveType::DataTypeFloat32
411    "Element.DataType.FLOAT_64",    // RSExportPrimitiveType::DataTypeFloat64
412    "Element.DataType.SIGNED_8",    // RSExportPrimitiveType::DataTypeSigned8
413    "Element.DataType.SIGNED_16",   // RSExportPrimitiveType::DataTypeSigned16
414    "Element.DataType.SIGNED_32",   // RSExportPrimitiveType::DataTypeSigned32
415    "Element.DataType.SIGNED_64",   // RSExportPrimitiveType::DataTypeSigned64
416    "Element.DataType.UNSIGNED_8",  // RSExportPrimitiveType::DataTypeUnsigned8
417    "Element.DataType.UNSIGNED_16", // RSExportPrimitiveType::DataTypeUnsigned16
418    "Element.DataType.UNSIGNED_32", // RSExportPrimitiveType::DataTypeUnsigned32
419    NULL,                           // RSExportPrimitiveType::DataTypeUnsigned64
420    "Element.DataType.BOOLEAN",     // RSExportPrimitiveType::DataTypeBoolean
421
422    // RSExportPrimitiveType::DataTypeUnsigned565
423    "Element.DataType.UNSIGNED_5_6_5",
424    // RSExportPrimitiveType::DataTypeUnsigned5551
425    "Element.DataType.UNSIGNED_5_5_5_1",
426    // RSExportPrimitiveType::DataTypeUnsigned4444
427    "Element.DataType.UNSIGNED_4_4_4_4",
428
429    // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct()
430    NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
431    NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
432    NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
433
434    "Element.DataType.RS_ELEMENT",  // RSExportPrimitiveType::DataTypeRSElement
435    "Element.DataType.RS_TYPE",     // RSExportPrimitiveType::DataTypeRSType
436      // RSExportPrimitiveType::DataTypeRSAllocation
437    "Element.DataType.RS_ALLOCATION",
438      // RSExportPrimitiveType::DataTypeRSSampler
439    "Element.DataType.RS_SAMPLER",
440      // RSExportPrimitiveType::DataTypeRSScript
441    "Element.DataType.RS_SCRIPT",
442      // RSExportPrimitiveType::DataTypeRSMesh
443    "Element.DataType.RS_MESH",
444      // RSExportPrimitiveType::DataTypeRSProgramFragment
445    "Element.DataType.RS_PROGRAM_FRAGMENT",
446      // RSExportPrimitiveType::DataTypeRSProgramVertex
447    "Element.DataType.RS_PROGRAM_VERTEX",
448      // RSExportPrimitiveType::DataTypeRSProgramRaster
449    "Element.DataType.RS_PROGRAM_RASTER",
450      // RSExportPrimitiveType::DataTypeRSProgramStore
451    "Element.DataType.RS_PROGRAM_STORE",
452      // RSExportPrimitiveType::DataTypeRSFont
453    "Element.DataType.RS_FONT",
454  };
455
456  if (static_cast<unsigned>(DT) <
457      (sizeof(ElementDataTypeNameMap) / sizeof(const char*)))
458    return ElementDataTypeNameMap[ DT ];
459  else
460    return NULL;
461}
462
463bool RSReflection::openScriptFile(Context &C,
464                                  const std::string &ClassName,
465                                  std::string &ErrorMsg) {
466  if (!C.mUseStdout) {
467    C.mOF.clear();
468    std::string _path = RSSlangReflectUtils::ComputePackagedPath(
469        mRSContext->getReflectJavaPathName().c_str(),
470        C.getPackageName().c_str());
471
472    RSSlangReflectUtils::mkdir_p(_path.c_str());
473    C.mOF.open((_path + "/" + ClassName + ".java").c_str());
474    if (!C.mOF.good()) {
475      ErrorMsg = "failed to open file '" + _path + "/" + ClassName
476          + ".java' for write";
477
478      return false;
479    }
480  }
481  return true;
482}
483
484/********************** Methods to generate script class **********************/
485bool RSReflection::genScriptClass(Context &C,
486                                  const std::string &ClassName,
487                                  std::string &ErrorMsg) {
488  // Open the file
489  if (!openScriptFile(C, ClassName, ErrorMsg)) {
490    return false;
491  }
492
493  if (!C.startClass(Context::AM_Public,
494                    false,
495                    ClassName,
496                    RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
497                    ErrorMsg))
498    return false;
499
500  genScriptClassConstructor(C);
501
502  // Reflect export variable
503  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
504           E = mRSContext->export_vars_end();
505       I != E;
506       I++)
507    genExportVariable(C, *I);
508
509  // Reflect export function
510  for (RSContext::const_export_func_iterator
511           I = mRSContext->export_funcs_begin(),
512           E = mRSContext->export_funcs_end();
513       I != E; I++)
514    genExportFunction(C, *I);
515
516  C.endClass();
517
518  return true;
519}
520
521void RSReflection::genScriptClassConstructor(Context &C) {
522  C.indent() << "// Constructor" << std::endl;
523  C.startFunction(Context::AM_Public,
524                  false,
525                  NULL,
526                  C.getClassName(),
527                  4,
528                  "RenderScript",
529                  "rs",
530                  "Resources",
531                  "resources",
532                  "int",
533                  "id",
534                  "boolean",
535                  "isRoot");
536  // Call constructor of super class
537  C.indent() << "super(rs, resources, id, isRoot);" << std::endl;
538
539  // If an exported variable has initial value, reflect it
540
541  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
542           E = mRSContext->export_vars_end();
543       I != E;
544       I++) {
545    const RSExportVar *EV = *I;
546    if (!EV->getInit().isUninit())
547      genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit());
548  }
549
550  C.endFunction();
551  return;
552}
553
554void RSReflection::genInitBoolExportVariable(Context &C,
555                                             const std::string &VarName,
556                                             const clang::APValue &Val) {
557  assert(!Val.isUninit() && "Not a valid initializer");
558
559  C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
560  assert((Val.getKind() == clang::APValue::Int) &&
561         "Bool type has wrong initial APValue");
562
563  C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
564          << ";" << std::endl;
565
566  return;
567}
568
569void RSReflection::genInitPrimitiveExportVariable(Context &C,
570                                                  const std::string &VarName,
571                                                  const clang::APValue &Val) {
572  assert(!Val.isUninit() && "Not a valid initializer");
573
574  C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
575  switch (Val.getKind()) {
576    case clang::APValue::Int: {
577      llvm::APInt api = Val.getInt();
578      C.out() << api.getSExtValue();
579      if (api.getBitWidth() > 32) {
580        C.out() << "L";
581      }
582      break;
583    }
584    case clang::APValue::Float: {
585      llvm::APFloat apf = Val.getFloat();
586      if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
587        C.out() << apf.convertToFloat() << "f";
588      } else {
589        C.out() << apf.convertToDouble();
590      }
591      break;
592    }
593
594    case clang::APValue::ComplexInt:
595    case clang::APValue::ComplexFloat:
596    case clang::APValue::LValue:
597    case clang::APValue::Vector: {
598      assert(false && "Primitive type cannot have such kind of initializer");
599      break;
600    }
601    default: {
602      assert(false && "Unknown kind of initializer");
603    }
604  }
605  C.out() << ";" << std::endl;
606
607  return;
608}
609
610void RSReflection::genInitExportVariable(Context &C,
611                                         const RSExportType *ET,
612                                         const std::string &VarName,
613                                         const clang::APValue &Val) {
614  assert(!Val.isUninit() && "Not a valid initializer");
615
616  switch (ET->getClass()) {
617    case RSExportType::ExportClassPrimitive: {
618      const RSExportPrimitiveType *EPT =
619          static_cast<const RSExportPrimitiveType*>(ET);
620      if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
621        genInitBoolExportVariable(C, VarName, Val);
622      } else {
623        genInitPrimitiveExportVariable(C, VarName, Val);
624      }
625      break;
626    }
627    case RSExportType::ExportClassPointer: {
628      if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
629        std::cout << "Initializer which is non-NULL to pointer type variable "
630                     "will be ignored" << std::endl;
631      break;
632    }
633    case RSExportType::ExportClassVector: {
634      const RSExportVectorType *EVT =
635          static_cast<const RSExportVectorType*>(ET);
636      switch (Val.getKind()) {
637        case clang::APValue::Int:
638        case clang::APValue::Float: {
639          for (unsigned i = 0; i < EVT->getNumElement(); i++) {
640            std::string Name =  VarName + "." + GetVectorAccessor(i);
641            genInitPrimitiveExportVariable(C, Name, Val);
642          }
643          break;
644        }
645        case clang::APValue::Vector: {
646          C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
647                     << GetVectorTypeName(EVT) << "();" << std::endl;
648
649          unsigned NumElements =
650              std::min(static_cast<unsigned>(EVT->getNumElement()),
651                       Val.getVectorLength());
652          for (unsigned i = 0; i < NumElements; i++) {
653            const clang::APValue &ElementVal = Val.getVectorElt(i);
654            std::string Name = VarName + "." + GetVectorAccessor(i);
655            genInitPrimitiveExportVariable(C, Name, ElementVal);
656          }
657          break;
658        }
659        case clang::APValue::Uninitialized:
660        case clang::APValue::ComplexInt:
661        case clang::APValue::ComplexFloat:
662        case clang::APValue::LValue: {
663          assert(false && "Unexpected type of value of initializer.");
664        }
665      }
666      break;
667    }
668    // TODO(zonr): Resolving initializer of a record (and matrix) type variable
669    // is complex. It cannot obtain by just simply evaluating the initializer
670    // expression.
671    case RSExportType::ExportClassMatrix:
672    case RSExportType::ExportClassConstantArray:
673    case RSExportType::ExportClassRecord: {
674#if 0
675      unsigned InitIndex = 0;
676      const RSExportRecordType *ERT =
677          static_cast<const RSExportRecordType*>(ET);
678
679      assert((Val.getKind() == clang::APValue::Vector) && "Unexpected type of "
680             "initializer for record type variable");
681
682      C.indent() << RS_EXPORT_VAR_PREFIX << VarName
683                 << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName()
684                 <<  "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
685
686      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
687               E = ERT->fields_end();
688           I != E;
689           I++) {
690        const RSExportRecordType::Field *F = *I;
691        std::string FieldName = VarName + "." + F->getName();
692
693        if (InitIndex > Val.getVectorLength())
694          break;
695
696        genInitPrimitiveExportVariable(C,
697                                       FieldName,
698                                       Val.getVectorElt(InitIndex++));
699      }
700#endif
701      assert(false && "Unsupported initializer for record/matrix/constant "
702                      "array type variable currently");
703      break;
704    }
705    default: {
706      assert(false && "Unknown class of type");
707    }
708  }
709  return;
710}
711
712void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) {
713  const RSExportType *ET = EV->getType();
714
715  C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX
716             << EV->getName() << " = " << C.getNextExportVarSlot() << ";"
717             << std::endl;
718
719  switch (ET->getClass()) {
720    case RSExportType::ExportClassPrimitive: {
721      genPrimitiveTypeExportVariable(C, EV);
722      break;
723    }
724    case RSExportType::ExportClassPointer: {
725      genPointerTypeExportVariable(C, EV);
726      break;
727    }
728    case RSExportType::ExportClassVector: {
729      genVectorTypeExportVariable(C, EV);
730      break;
731    }
732    case RSExportType::ExportClassMatrix: {
733      genMatrixTypeExportVariable(C, EV);
734      break;
735    }
736    case RSExportType::ExportClassConstantArray: {
737      genConstantArrayTypeExportVariable(C, EV);
738      break;
739    }
740    case RSExportType::ExportClassRecord: {
741      genRecordTypeExportVariable(C, EV);
742      break;
743    }
744    default: {
745      assert(false && "Unknown class of type");
746    }
747  }
748
749  return;
750}
751
752void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) {
753  C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX
754             << EF->getName() << " = " << C.getNextExportFuncSlot() << ";"
755             << std::endl;
756
757  // invoke_*()
758  Context::ArgTy Args;
759
760  if (EF->hasParam()) {
761    for (RSExportFunc::const_param_iterator I = EF->params_begin(),
762             E = EF->params_end();
763         I != E;
764         I++) {
765      Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
766                                    (*I)->getName()));
767    }
768  }
769
770  C.startFunction(Context::AM_Public,
771                  false,
772                  "void",
773                  "invoke_" + EF->getName(),
774                  Args);
775
776  if (!EF->hasParam()) {
777    C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");"
778               << std::endl;
779  } else {
780    const RSExportRecordType *ERT = EF->getParamPacketType();
781    std::string FieldPackerName = EF->getName() + "_fp";
782
783    if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
784      genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
785
786    C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", "
787               << FieldPackerName << ");" << std::endl;
788  }
789
790  C.endFunction();
791  return;
792}
793
794void RSReflection::genPrimitiveTypeExportVariable(Context &C,
795                                                  const RSExportVar *EV) {
796  assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
797         "Variable should be type of primitive here");
798
799  const RSExportPrimitiveType *EPT =
800      static_cast<const RSExportPrimitiveType*>(EV->getType());
801  const char *TypeName = GetPrimitiveTypeName(EPT);
802
803  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
804             << EV->getName() << ";" << std::endl;
805
806  // set_*()
807  if (!EV->isConst()) {
808    C.startFunction(Context::AM_Public,
809                    false,
810                    "void",
811                    "set_" + EV->getName(),
812                    1,
813                    TypeName,
814                    "v");
815    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
816
817    if (EPT->isRSObjectType())
818      C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
819                 << ", (v == null) ? 0 : v.getID());" << std::endl;
820    else
821      C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
822                 << ", v);" << std::endl;
823
824    C.endFunction();
825  }
826
827  genGetExportVariable(C, TypeName, EV->getName());
828
829  return;
830}
831
832void RSReflection::genPointerTypeExportVariable(Context &C,
833                                                const RSExportVar *EV) {
834  const RSExportType *ET = EV->getType();
835  const RSExportType *PointeeType;
836  std::string TypeName;
837
838  assert((ET->getClass() == RSExportType::ExportClassPointer) &&
839         "Variable should be type of pointer here");
840
841  PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
842  TypeName = GetTypeName(ET);
843
844  // bind_*()
845  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
846             << EV->getName() << ";" << std::endl;
847
848  C.startFunction(Context::AM_Public,
849                  false,
850                  "void",
851                  "bind_" + EV->getName(),
852                  1,
853                  TypeName.c_str(),
854                  "v");
855
856  C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
857  C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX
858             << EV->getName() << ");" << std::endl;
859
860  if (PointeeType->getClass() == RSExportType::ExportClassRecord)
861    C.indent() << "else bindAllocation(v.getAllocation(), "
862        RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");"
863               << std::endl;
864  else
865    C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX
866               << EV->getName() << ");" << std::endl;
867
868  C.endFunction();
869
870  genGetExportVariable(C, TypeName, EV->getName());
871
872  return;
873}
874
875void RSReflection::genVectorTypeExportVariable(Context &C,
876                                               const RSExportVar *EV) {
877  assert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
878         "Variable should be type of vector here");
879
880  const RSExportVectorType *EVT =
881      static_cast<const RSExportVectorType*>(EV->getType());
882  const char *TypeName = GetVectorTypeName(EVT);
883  const char *FieldPackerName = "fp";
884
885  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
886             << EV->getName() << ";" << std::endl;
887
888  // set_*()
889  if (!EV->isConst()) {
890    C.startFunction(Context::AM_Public,
891                    false,
892                    "void",
893                    "set_" + EV->getName(),
894                    1,
895                    TypeName,
896                    "v");
897    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
898
899    if (genCreateFieldPacker(C, EVT, FieldPackerName))
900      genPackVarOfType(C, EVT, "v", FieldPackerName);
901    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
902               << FieldPackerName << ");" << std::endl;
903
904    C.endFunction();
905  }
906
907  genGetExportVariable(C, TypeName, EV->getName());
908  return;
909}
910
911void RSReflection::genMatrixTypeExportVariable(Context &C,
912                                               const RSExportVar *EV) {
913  assert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
914         "Variable should be type of matrix here");
915
916  const RSExportMatrixType *EMT =
917      static_cast<const RSExportMatrixType*>(EV->getType());
918  const char *TypeName = GetMatrixTypeName(EMT);
919  const char *FieldPackerName = "fp";
920
921  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
922             << EV->getName() << ";" << std::endl;
923
924  // set_*()
925  if (!EV->isConst()) {
926    C.startFunction(Context::AM_Public,
927                    false,
928                    "void",
929                    "set_" + EV->getName(),
930                    1,
931                    TypeName, "v");
932    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
933
934    if (genCreateFieldPacker(C, EMT, FieldPackerName))
935      genPackVarOfType(C, EMT, "v", FieldPackerName);
936    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
937               << FieldPackerName << ");" << std::endl;
938
939    C.endFunction();
940  }
941
942  genGetExportVariable(C, TypeName, EV->getName());
943  return;
944}
945
946void RSReflection::genConstantArrayTypeExportVariable(Context &C,
947                                                      const RSExportVar *EV) {
948  assert((EV->getType()->getClass() == RSExportType::ExportClassConstantArray)&&
949         "Variable should be type of constant array here");
950
951  const RSExportConstantArrayType *ECAT =
952      static_cast<const RSExportConstantArrayType*>(EV->getType());
953  std::string TypeName = GetTypeName(ECAT);
954  const char *FieldPackerName = "fp";
955
956  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
957             << EV->getName() << ";" << std::endl;
958
959  // set_*()
960  if (!EV->isConst()) {
961    C.startFunction(Context::AM_Public,
962                    false,
963                    "void",
964                    "set_" + EV->getName(),
965                    1,
966                    TypeName.c_str(), "v");
967    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
968
969    if (genCreateFieldPacker(C, ECAT, FieldPackerName))
970      genPackVarOfType(C, ECAT, "v", FieldPackerName);
971    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
972               << FieldPackerName << ");" << std::endl;
973
974    C.endFunction();
975  }
976
977  genGetExportVariable(C, TypeName, EV->getName());
978  return;
979}
980
981void RSReflection::genRecordTypeExportVariable(Context &C,
982                                               const RSExportVar *EV) {
983  assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
984         "Variable should be type of struct here");
985
986  const RSExportRecordType *ERT =
987      static_cast<const RSExportRecordType*>(EV->getType());
988  std::string TypeName =
989      RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
990  const char *FieldPackerName = "fp";
991
992  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
993             << EV->getName() << ";" << std::endl;
994
995  // set_*()
996  if (!EV->isConst()) {
997    C.startFunction(Context::AM_Public,
998                    false,
999                    "void",
1000                    "set_" + EV->getName(),
1001                    1,
1002                    TypeName.c_str(),
1003                    "v");
1004    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1005
1006    if (genCreateFieldPacker(C, ERT, FieldPackerName))
1007      genPackVarOfType(C, ERT, "v", FieldPackerName);
1008    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
1009               << ", " << FieldPackerName << ");" << std::endl;
1010
1011    C.endFunction();
1012  }
1013
1014  genGetExportVariable(C, TypeName.c_str(), EV->getName());
1015  return;
1016}
1017
1018void RSReflection::genGetExportVariable(Context &C,
1019                                        const std::string &TypeName,
1020                                        const std::string &VarName) {
1021  C.startFunction(Context::AM_Public,
1022                  false,
1023                  TypeName.c_str(),
1024                  "get_" + VarName,
1025                  0);
1026
1027  C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl;
1028
1029  C.endFunction();
1030  return;
1031}
1032
1033/******************* Methods to generate script class /end *******************/
1034
1035bool RSReflection::genCreateFieldPacker(Context &C,
1036                                        const RSExportType *ET,
1037                                        const char *FieldPackerName) {
1038  size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
1039  if (AllocSize > 0)
1040    C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1041               << AllocSize << ");" << std::endl;
1042  else
1043    return false;
1044  return true;
1045}
1046
1047void RSReflection::genPackVarOfType(Context &C,
1048                                    const RSExportType *ET,
1049                                    const char *VarName,
1050                                    const char *FieldPackerName) {
1051  switch (ET->getClass()) {
1052    case RSExportType::ExportClassPrimitive:
1053    case RSExportType::ExportClassVector: {
1054      C.indent() << FieldPackerName << "."
1055                 << GetPackerAPIName(
1056                     static_cast<const RSExportPrimitiveType*>(ET))
1057                 << "(" << VarName << ");" << std::endl;
1058      break;
1059    }
1060    case RSExportType::ExportClassPointer: {
1061      // Must reflect as type Allocation in Java
1062      const RSExportType *PointeeType =
1063          static_cast<const RSExportPointerType*>(ET)->getPointeeType();
1064
1065      if (PointeeType->getClass() != RSExportType::ExportClassRecord)
1066        C.indent() << FieldPackerName << ".addI32(" << VarName
1067                   << ".getPtr());" << std::endl;
1068      else
1069        C.indent() << FieldPackerName << ".addI32(" << VarName
1070                   << ".getAllocation().getPtr());" << std::endl;
1071      break;
1072    }
1073    case RSExportType::ExportClassMatrix: {
1074      C.indent() << FieldPackerName << ".addObj(" << VarName << ");"
1075                 << std::endl;
1076      break;
1077    }
1078    case RSExportType::ExportClassConstantArray: {
1079      const RSExportConstantArrayType *ECAT =
1080          static_cast<const RSExportConstantArrayType *>(ET);
1081      C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)";
1082      C.startBlock();
1083
1084      std::string ElementVarName(VarName);
1085      ElementVarName.append("[ct]");
1086      genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
1087                       FieldPackerName);
1088
1089      C.endBlock();
1090      break;
1091    }
1092    case RSExportType::ExportClassRecord: {
1093      const RSExportRecordType *ERT =
1094          static_cast<const RSExportRecordType*>(ET);
1095      // Relative pos from now on in field packer
1096      unsigned Pos = 0;
1097
1098      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1099               E = ERT->fields_end();
1100           I != E;
1101           I++) {
1102        const RSExportRecordType::Field *F = *I;
1103        std::string FieldName;
1104        size_t FieldOffset = F->getOffsetInParent();
1105        size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1106        size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
1107
1108        if (VarName != NULL)
1109          FieldName = VarName + ("." + F->getName());
1110        else
1111          FieldName = F->getName();
1112
1113        if (FieldOffset > Pos)
1114          C.indent() << FieldPackerName << ".skip("
1115                     << (FieldOffset - Pos) << ");" << std::endl;
1116
1117        genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);
1118
1119        // There is padding in the field type
1120        if (FieldAllocSize > FieldStoreSize)
1121            C.indent() << FieldPackerName << ".skip("
1122                       << (FieldAllocSize - FieldStoreSize)
1123                       << ");" << std::endl;
1124
1125          Pos = FieldOffset + FieldAllocSize;
1126      }
1127
1128      // There maybe some padding after the struct
1129      size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos;
1130      if (Padding > 0)
1131        C.indent() << FieldPackerName << ".skip(" << Padding << ");"
1132                   << std::endl;
1133      break;
1134    }
1135    default: {
1136      assert(false && "Unknown class of type");
1137    }
1138  }
1139
1140  return;
1141}
1142
1143void RSReflection::genAllocateVarOfType(Context &C,
1144                                        const RSExportType *T,
1145                                        const std::string &VarName) {
1146  switch (T->getClass()) {
1147    case RSExportType::ExportClassPrimitive: {
1148      // Primitive type like int in Java has its own storage once it's declared.
1149      //
1150      // FIXME: Should we allocate storage for RS object?
1151      // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
1152      //  C.indent() << VarName << " = new " << GetTypeName(T) << "();"
1153      //             << std::endl;
1154      break;
1155    }
1156    case RSExportType::ExportClassPointer: {
1157      // Pointer type is an instance of Allocation or a TypeClass whose value is
1158      // expected to be assigned by programmer later in Java program. Therefore
1159      // we don't reflect things like [VarName] = new Allocation();
1160      C.indent() << VarName << " = null;" << std::endl;
1161      break;
1162    }
1163    case RSExportType::ExportClassConstantArray: {
1164      const RSExportConstantArrayType *ECAT =
1165          static_cast<const RSExportConstantArrayType *>(T);
1166      const RSExportType *ElementType = ECAT->getElementType();
1167
1168      // Primitive type element doesn't need allocation code.
1169      if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
1170        C.indent() << VarName << " = new " << GetTypeName(ElementType)
1171                   << "[" << ECAT->getSize() << "];" << std::endl;
1172
1173        C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; "
1174                            "$ct++)";
1175        C.startBlock();
1176
1177        std::string ElementVarName(VarName);
1178        ElementVarName.append("[$ct]");
1179        genAllocateVarOfType(C, ElementType, ElementVarName);
1180
1181        C.endBlock();
1182      }
1183      break;
1184    }
1185    case RSExportType::ExportClassVector:
1186    case RSExportType::ExportClassMatrix:
1187    case RSExportType::ExportClassRecord: {
1188      C.indent() << VarName << " = new " << GetTypeName(T) << "();"
1189                 << std::endl;
1190      break;
1191    }
1192  }
1193  return;
1194}
1195
1196void RSReflection::genNewItemBufferIfNull(Context &C, const char *Index) {
1197  C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "
1198                  RS_TYPE_ITEM_BUFFER_NAME" = "
1199                    "new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];"
1200             << std::endl;
1201  if (Index != NULL)
1202    C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) "
1203                    RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = "
1204                      "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
1205  return;
1206}
1207
1208void RSReflection::genNewItemBufferPackerIfNull(Context &C) {
1209  C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) "
1210                  RS_TYPE_ITEM_BUFFER_PACKER_NAME" = "
1211                    "new FieldPacker("
1212                      RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX()/* count */"
1213                    ");" << std::endl;
1214  return;
1215}
1216
1217/********************** Methods to generate type class  **********************/
1218bool RSReflection::genTypeClass(Context &C,
1219                                const RSExportRecordType *ERT,
1220                                std::string &ErrorMsg) {
1221  std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
1222
1223  // Open the file
1224  if (!openScriptFile(C, ClassName, ErrorMsg)) {
1225    return false;
1226  }
1227
1228  if (!C.startClass(Context::AM_Public,
1229                    false,
1230                    ClassName,
1231                    RS_TYPE_CLASS_SUPER_CLASS_NAME,
1232                    ErrorMsg))
1233    return false;
1234
1235  genTypeItemClass(C, ERT);
1236
1237  // Declare item buffer and item buffer packer
1238  C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]"
1239      ";" << std::endl;
1240  C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";"
1241             << std::endl;
1242
1243  genTypeClassConstructor(C, ERT);
1244  genTypeClassCopyToArray(C, ERT);
1245  genTypeClassItemSetter(C, ERT);
1246  genTypeClassItemGetter(C, ERT);
1247  genTypeClassComponentSetter(C, ERT);
1248  genTypeClassComponentGetter(C, ERT);
1249  genTypeClassCopyAll(C, ERT);
1250
1251  C.endClass();
1252
1253  C.resetFieldIndex();
1254  C.clearFieldIndexMap();
1255
1256  return true;
1257}
1258
1259void RSReflection::genTypeItemClass(Context &C, const RSExportRecordType *ERT) {
1260  C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
1261  C.startBlock();
1262
1263  C.indent() << "public static final int sizeof = "
1264             << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl;
1265
1266  // Member elements
1267  C.out() << std::endl;
1268  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1269           FE = ERT->fields_end();
1270       FI != FE;
1271       FI++) {
1272    C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
1273               << ";" << std::endl;
1274  }
1275
1276  // Constructor
1277  C.out() << std::endl;
1278  C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
1279  C.startBlock();
1280
1281  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1282           FE = ERT->fields_end();
1283       FI != FE;
1284       FI++) {
1285    const RSExportRecordType::Field *F = *FI;
1286    genAllocateVarOfType(C, F->getType(), F->getName());
1287  }
1288
1289  // end Constructor
1290  C.endBlock();
1291
1292  // end Item class
1293  C.endBlock();
1294
1295  return;
1296}
1297
1298void RSReflection::genTypeClassConstructor(Context &C,
1299                                           const RSExportRecordType *ERT) {
1300  const char *RenderScriptVar = "rs";
1301
1302  C.startFunction(Context::AM_Public,
1303                  true,
1304                  "Element",
1305                  "createElement",
1306                  1,
1307                  "RenderScript",
1308                  RenderScriptVar);
1309  genBuildElement(C, ERT, RenderScriptVar);
1310  C.endFunction();
1311
1312  C.startFunction(Context::AM_Public,
1313                  false,
1314                  NULL,
1315                  C.getClassName(),
1316                  2,
1317                  "RenderScript",
1318                  RenderScriptVar,
1319                  "int",
1320                  "count");
1321
1322  C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
1323  C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
1324  C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
1325             << std::endl;
1326  // Call init() in super class
1327  C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl;
1328  C.endFunction();
1329
1330  return;
1331}
1332
1333void RSReflection::genTypeClassCopyToArray(Context &C,
1334                                           const RSExportRecordType *ERT) {
1335  C.startFunction(Context::AM_Private,
1336                  false,
1337                  "void",
1338                  "copyToArray",
1339                  2,
1340                  RS_TYPE_ITEM_CLASS_NAME,
1341                  "i",
1342                  "int",
1343                  "index");
1344
1345  genNewItemBufferPackerIfNull(C);
1346  C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1347                ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
1348             << std::endl;
1349
1350  genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
1351
1352  C.endFunction();
1353  return;
1354}
1355
1356void RSReflection::genTypeClassItemSetter(Context &C,
1357                                          const RSExportRecordType *ERT) {
1358  C.startFunction(Context::AM_Public,
1359                  false,
1360                  "void",
1361                  "set",
1362                  3,
1363                  RS_TYPE_ITEM_CLASS_NAME,
1364                  "i",
1365                  "int",
1366                  "index",
1367                  "boolean",
1368                  "copyNow");
1369  genNewItemBufferIfNull(C, NULL);
1370  C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl;
1371
1372  C.indent() << "if (copyNow) ";
1373  C.startBlock();
1374
1375  C.indent() << "copyToArray(i, index);" << std::endl;
1376  C.indent() << "mAllocation.subData1D(index, 1, "
1377                  RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << std::endl;
1378
1379  // End of if (copyNow)
1380  C.endBlock();
1381
1382  C.endFunction();
1383  return;
1384}
1385
1386void RSReflection::genTypeClassItemGetter(Context &C,
1387                                          const RSExportRecordType *ERT) {
1388  C.startFunction(Context::AM_Public,
1389                  false,
1390                  RS_TYPE_ITEM_CLASS_NAME,
1391                  "get",
1392                  1,
1393                  "int",
1394                  "index");
1395  C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;"
1396             << std::endl;
1397  C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl;
1398  C.endFunction();
1399  return;
1400}
1401
1402void RSReflection::genTypeClassComponentSetter(Context &C,
1403                                               const RSExportRecordType *ERT) {
1404  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1405           FE = ERT->fields_end();
1406       FI != FE;
1407       FI++) {
1408    const RSExportRecordType::Field *F = *FI;
1409    size_t FieldOffset = F->getOffsetInParent();
1410    size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1411    unsigned FieldIndex = C.getFieldIndex(F);
1412
1413    C.startFunction(Context::AM_Public,
1414                    false,
1415                    "void",
1416                    "set_" + F->getName(), 3,
1417                    "int",
1418                    "index",
1419                    GetTypeName(F->getType()).c_str(),
1420                    "v",
1421                    "boolean",
1422                    "copyNow");
1423    genNewItemBufferPackerIfNull(C);
1424    genNewItemBufferIfNull(C, "index");
1425    C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
1426               << " = v;" << std::endl;
1427
1428    C.indent() << "if (copyNow) ";
1429    C.startBlock();
1430
1431    if (FieldOffset > 0)
1432      C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1433                    ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + "
1434                 << FieldOffset << ");" << std::endl;
1435    else
1436      C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1437                    ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
1438                 << std::endl;
1439    genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
1440
1441    C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");"
1442               << std::endl;
1443    genPackVarOfType(C, F->getType(), "v", "fp");
1444    C.indent() << "mAllocation.subElementData(index, " << FieldIndex << ", fp);"
1445               << std::endl;
1446
1447    // End of if (copyNow)
1448    C.endBlock();
1449
1450    C.endFunction();
1451  }
1452  return;
1453}
1454
1455void RSReflection::genTypeClassComponentGetter(Context &C,
1456                                               const RSExportRecordType *ERT) {
1457  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1458           FE = ERT->fields_end();
1459       FI != FE;
1460       FI++) {
1461    const RSExportRecordType::Field *F = *FI;
1462    C.startFunction(Context::AM_Public,
1463                    false,
1464                    GetTypeName(F->getType()).c_str(),
1465                    "get_" + F->getName(),
1466                    1,
1467                    "int",
1468                    "index");
1469    C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return "
1470               << GetTypeNullValue(F->getType()) << ";" << std::endl;
1471    C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
1472               << ";" << std::endl;
1473    C.endFunction();
1474  }
1475  return;
1476}
1477
1478void RSReflection::genTypeClassCopyAll(Context &C,
1479                                       const RSExportRecordType *ERT) {
1480  C.startFunction(Context::AM_Public, false, "void", "copyAll", 0);
1481
1482  C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)"
1483                  " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);"
1484             << std::endl;
1485  C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());"
1486             << std::endl;
1487
1488  C.endFunction();
1489  return;
1490}
1491
1492/******************** Methods to generate type class /end ********************/
1493
1494/********** Methods to create Element in Java of given record type ***********/
1495void RSReflection::genBuildElement(Context &C, const RSExportRecordType *ERT,
1496                                   const char *RenderScriptVar) {
1497  const char *ElementBuilderName = "eb";
1498
1499  // Create element builder
1500  //    C.startBlock(true);
1501
1502  C.indent() << "Element.Builder " << ElementBuilderName << " = "
1503      "new Element.Builder(" << RenderScriptVar << ");" << std::endl;
1504
1505  // eb.add(...)
1506  genAddElementToElementBuilder(C,
1507                                ERT,
1508                                "",
1509                                ElementBuilderName,
1510                                RenderScriptVar);
1511
1512  C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
1513
1514  //   C.endBlock();
1515  return;
1516}
1517
1518#define EB_ADD(x)                                                   \
1519  C.indent() << ElementBuilderName                                  \
1520             << ".add(Element." << x << ", \"" << VarName << "\");" \
1521             << std::endl;                                          \
1522  C.incFieldIndex()
1523
1524void RSReflection::genAddElementToElementBuilder(Context &C,
1525                                                 const RSExportType *ET,
1526                                                 const std::string &VarName,
1527                                                 const char *ElementBuilderName,
1528                                                 const char *RenderScriptVar) {
1529  const char *ElementConstruct = GetBuiltinElementConstruct(ET);
1530
1531  if (ElementConstruct != NULL) {
1532    EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
1533  } else {
1534    if ((ET->getClass() == RSExportType::ExportClassPrimitive) ||
1535        (ET->getClass() == RSExportType::ExportClassVector)) {
1536      const RSExportPrimitiveType *EPT =
1537          static_cast<const RSExportPrimitiveType*>(ET);
1538      const char *DataKindName = GetElementDataKindName(EPT->getKind());
1539      const char *DataTypeName = GetElementDataTypeName(EPT->getType());
1540      int Size = (ET->getClass() == RSExportType::ExportClassVector) ?
1541          static_cast<const RSExportVectorType*>(ET)->getNumElement() :
1542          1;
1543
1544      switch (EPT->getKind()) {
1545        case RSExportPrimitiveType::DataKindPixelL:
1546        case RSExportPrimitiveType::DataKindPixelA:
1547        case RSExportPrimitiveType::DataKindPixelLA:
1548        case RSExportPrimitiveType::DataKindPixelRGB:
1549        case RSExportPrimitiveType::DataKindPixelRGBA: {
1550          // Element.createPixel()
1551          EB_ADD("createPixel(" << RenderScriptVar << ", "
1552                                << DataTypeName << ", "
1553                                << DataKindName << ")");
1554          break;
1555        }
1556        case RSExportPrimitiveType::DataKindUser:
1557        default: {
1558          if (EPT->getClass() == RSExportType::ExportClassPrimitive) {
1559            // Element.createUser()
1560            EB_ADD("createUser(" << RenderScriptVar << ", "
1561                                 << DataTypeName << ")");
1562          } else {
1563            assert((ET->getClass() == RSExportType::ExportClassVector) &&
1564                   "Unexpected type.");
1565            EB_ADD("createVector(" << RenderScriptVar << ", "
1566                                   << DataTypeName << ", "
1567                                   << Size << ")");
1568          }
1569          break;
1570        }
1571      }
1572#ifndef NDEBUG
1573    } else if (ET->getClass() == RSExportType::ExportClassPointer) {
1574      // Pointer type variable should be resolved in
1575      // GetBuiltinElementConstruct()
1576      assert(false && "??");
1577    } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
1578      // Matrix type variable should be resolved
1579      // in GetBuiltinElementConstruct()
1580      assert(false && "??");
1581#endif
1582    } else if (ET->getClass() == RSExportType::ExportClassConstantArray) {
1583      const RSExportConstantArrayType *ECAT =
1584          static_cast<const RSExportConstantArrayType *>(ET);
1585      C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)";
1586      C.startBlock();
1587
1588      std::string ElementVarName(VarName);
1589      ElementVarName.append("[\" + ct + \"]");
1590      genAddElementToElementBuilder(C,
1591                                    ECAT->getElementType(),
1592                                    ElementVarName,
1593                                    ElementBuilderName,
1594                                    RenderScriptVar);
1595
1596      C.endBlock();
1597    } else if (ET->getClass() == RSExportType::ExportClassRecord) {
1598      // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
1599      //
1600      // TODO(zonr): Generalize these two function such that there's no
1601      //             duplicated codes.
1602      const RSExportRecordType *ERT =
1603          static_cast<const RSExportRecordType*>(ET);
1604      int Pos = 0;    // relative pos from now on
1605
1606      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1607               E = ERT->fields_end();
1608           I != E;
1609           I++) {
1610        const RSExportRecordType::Field *F = *I;
1611        std::string FieldName;
1612        int FieldOffset = F->getOffsetInParent();
1613        int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1614        int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
1615
1616        if (!VarName.empty())
1617          FieldName = VarName + "." + F->getName();
1618        else
1619          FieldName = F->getName();
1620
1621        // Alignment
1622        genAddPaddingToElementBuiler(C,
1623                                     (FieldOffset - Pos),
1624                                     ElementBuilderName,
1625                                     RenderScriptVar);
1626
1627        // eb.add(...)
1628        C.addFieldIndexMapping(F);
1629        genAddElementToElementBuilder(C,
1630                                      F->getType(),
1631                                      FieldName,
1632                                      ElementBuilderName,
1633                                      RenderScriptVar);
1634
1635        // There is padding within the field type
1636        genAddPaddingToElementBuiler(C,
1637                                     (FieldAllocSize - FieldStoreSize),
1638                                     ElementBuilderName,
1639                                     RenderScriptVar);
1640
1641        Pos = FieldOffset + FieldAllocSize;
1642      }
1643
1644      // There maybe some padding after the struct
1645      //unsigned char align = RSExportType::GetTypeAlignment(ERT);
1646      //size_t siz = RSExportType::GetTypeAllocSize(ERT);
1647      size_t siz1 = RSExportType::GetTypeStoreSize(ERT);
1648
1649      genAddPaddingToElementBuiler(C,
1650                                   siz1 - Pos,
1651                                   ElementBuilderName,
1652                                   RenderScriptVar);
1653    } else {
1654      assert(false && "Unknown class of type");
1655    }
1656  }
1657}
1658
1659void RSReflection::genAddPaddingToElementBuiler(Context &C,
1660                                                int PaddingSize,
1661                                                const char *ElementBuilderName,
1662                                                const char *RenderScriptVar) {
1663  while (PaddingSize > 0) {
1664    const std::string &VarName = C.createPaddingField();
1665    if (PaddingSize >= 4) {
1666      EB_ADD("U32(" << RenderScriptVar << ")");
1667      PaddingSize -= 4;
1668    } else if (PaddingSize >= 2) {
1669      EB_ADD("U16(" << RenderScriptVar << ")");
1670      PaddingSize -= 2;
1671    } else if (PaddingSize >= 1) {
1672      EB_ADD("U8(" << RenderScriptVar << ")");
1673      PaddingSize -= 1;
1674    }
1675  }
1676  return;
1677}
1678
1679#undef EB_ADD
1680/******** Methods to create Element in Java of given record type /end ********/
1681
1682bool RSReflection::reflect(const char *OutputPackageName,
1683                           const std::string &InputFileName,
1684                           const std::string &OutputBCFileName) {
1685  Context *C = NULL;
1686  std::string ResourceId = "";
1687
1688  if (!GetClassNameFromFileName(OutputBCFileName, ResourceId))
1689    return false;
1690
1691  if (ResourceId.empty())
1692    ResourceId = "<Resource ID>";
1693
1694  if ((OutputPackageName == NULL) ||
1695      (*OutputPackageName == '\0') ||
1696      strcmp(OutputPackageName, "-") == 0)
1697    C = new Context(InputFileName, "<Package Name>", ResourceId, true);
1698  else
1699    C = new Context(InputFileName, OutputPackageName, ResourceId, false);
1700
1701  if (C != NULL) {
1702    std::string ErrorMsg, ScriptClassName;
1703    // class ScriptC_<ScriptName>
1704    if (!GetClassNameFromFileName(InputFileName, ScriptClassName))
1705      return false;
1706
1707    if (ScriptClassName.empty())
1708      ScriptClassName = "<Input Script Name>";
1709
1710    ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);
1711
1712    if (mRSContext->getLicenseNote() != NULL) {
1713      C->setLicenseNote(*(mRSContext->getLicenseNote()));
1714    }
1715
1716    if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
1717      std::cerr << "Failed to generate class " << ScriptClassName << " ("
1718                << ErrorMsg << ")" << std::endl;
1719      return false;
1720    }
1721
1722    // class ScriptField_<TypeName>
1723    for (RSContext::const_export_type_iterator TI =
1724             mRSContext->export_types_begin(),
1725             TE = mRSContext->export_types_end();
1726         TI != TE;
1727         TI++) {
1728      const RSExportType *ET = TI->getValue();
1729
1730      if (ET->getClass() == RSExportType::ExportClassRecord) {
1731        const RSExportRecordType *ERT =
1732            static_cast<const RSExportRecordType*>(ET);
1733
1734        if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
1735          std::cerr << "Failed to generate type class for struct '"
1736                    << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl;
1737          return false;
1738        }
1739      }
1740    }
1741  }
1742
1743  return true;
1744}
1745
1746/************************** RSReflection::Context **************************/
1747const char *const RSReflection::Context::ApacheLicenseNote =
1748    "/*\n"
1749    " * Copyright (C) 2010 The Android Open Source Project\n"
1750    " *\n"
1751    " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
1752    " * you may not use this file except in compliance with the License.\n"
1753    " * You may obtain a copy of the License at\n"
1754    " *\n"
1755    " *      http://www.apache.org/licenses/LICENSE-2.0\n"
1756    " *\n"
1757    " * Unless required by applicable law or agreed to in writing, software\n"
1758    " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
1759    " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
1760    "implied.\n"
1761    " * See the License for the specific language governing permissions and\n"
1762    " * limitations under the License.\n"
1763    " */\n"
1764    "\n";
1765
1766const char *const RSReflection::Context::Import[] = {
1767  // RenderScript java class
1768  "android.renderscript.*",
1769  // Import R
1770  "android.content.res.Resources",
1771  // Import for debugging
1772  "android.util.Log",
1773};
1774
1775const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) {
1776  switch (AM) {
1777    case AM_Public: return "public"; break;
1778    case AM_Protected: return "protected"; break;
1779    case AM_Private: return "private"; break;
1780    default: return ""; break;
1781  }
1782}
1783
1784bool RSReflection::Context::startClass(AccessModifier AM,
1785                                       bool IsStatic,
1786                                       const std::string &ClassName,
1787                                       const char *SuperClassName,
1788                                       std::string &ErrorMsg) {
1789  if (mVerbose)
1790    std::cout << "Generating " << ClassName << ".java ..." << std::endl;
1791
1792  // License
1793  out() << mLicenseNote;
1794
1795  // Notice of generated file
1796  out() << "/*" << std::endl;
1797  out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl;
1798  out() << " * The source RenderScript file: " << mInputRSFile << std::endl;
1799  out() << " */" << std::endl;
1800
1801  // Package
1802  if (!mPackageName.empty())
1803    out() << "package " << mPackageName << ";" << std::endl;
1804  out() << std::endl;
1805
1806  // Imports
1807  for (unsigned i = 0;i < (sizeof(Import) / sizeof(const char*)); i++)
1808    out() << "import " << Import[i] << ";" << std::endl;
1809  out() << std::endl;
1810
1811  // All reflected classes should be annotated as hidden, so that they won't
1812  // be exposed in SDK.
1813  out() << "/**" << std::endl;
1814  out() << " * @hide" << std::endl;
1815  out() << " */" << std::endl;
1816
1817  out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
1818        << ClassName;
1819  if (SuperClassName != NULL)
1820    out() << " extends " << SuperClassName;
1821
1822  startBlock();
1823
1824  mClassName = ClassName;
1825
1826  return true;
1827}
1828
1829void RSReflection::Context::endClass() {
1830  endBlock();
1831  if (!mUseStdout)
1832    mOF.close();
1833  clear();
1834  return;
1835}
1836
1837void RSReflection::Context::startBlock(bool ShouldIndent) {
1838  if (ShouldIndent)
1839    indent() << "{" << std::endl;
1840  else
1841    out() << " {" << std::endl;
1842  incIndentLevel();
1843  return;
1844}
1845
1846void RSReflection::Context::endBlock() {
1847  decIndentLevel();
1848  indent() << "}" << std::endl << std::endl;
1849  return;
1850}
1851
1852void RSReflection::Context::startTypeClass(const std::string &ClassName) {
1853  indent() << "public static class " << ClassName;
1854  startBlock();
1855  return;
1856}
1857
1858void RSReflection::Context::endTypeClass() {
1859  endBlock();
1860  return;
1861}
1862
1863void RSReflection::Context::startFunction(AccessModifier AM,
1864                                          bool IsStatic,
1865                                          const char *ReturnType,
1866                                          const std::string &FunctionName,
1867                                          int Argc, ...) {
1868  ArgTy Args;
1869  va_list vl;
1870  va_start(vl, Argc);
1871
1872  for (int i = 0; i < Argc; i++) {
1873    const char *ArgType = va_arg(vl, const char*);
1874    const char *ArgName = va_arg(vl, const char*);
1875
1876    Args.push_back(std::make_pair(ArgType, ArgName));
1877  }
1878  va_end(vl);
1879
1880  startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
1881
1882  return;
1883}
1884
1885void RSReflection::Context::startFunction(AccessModifier AM,
1886                                          bool IsStatic,
1887                                          const char *ReturnType,
1888                                          const std::string &FunctionName,
1889                                          const ArgTy &Args) {
1890  indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
1891           << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";
1892
1893  bool FirstArg = true;
1894  for (ArgTy::const_iterator I = Args.begin(), E = Args.end();
1895       I != E;
1896       I++) {
1897    if (!FirstArg)
1898      out() << ", ";
1899    else
1900      FirstArg = false;
1901
1902    out() << I->first << " " << I->second;
1903  }
1904
1905  out() << ")";
1906  startBlock();
1907
1908  return;
1909}
1910
1911void RSReflection::Context::endFunction() {
1912  endBlock();
1913  return;
1914}
1915