/*
 * Copyright 2010-2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "slang_rs_reflection.h"

#include <sys/stat.h>

#include <cstdarg>
#include <cctype>

#include <algorithm>
#include <sstream>
#include <string>
#include <utility>

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringExtras.h"

#include "os_sep.h"
#include "slang_rs_context.h"
#include "slang_rs_export_var.h"
#include "slang_rs_export_foreach.h"
#include "slang_rs_export_func.h"
#include "slang_rs_reflect_utils.h"
#include "slang_version.h"
#include "slang_utils.h"

#include "slang_rs_reflection_base.h"

#define RS_SCRIPT_CLASS_NAME_PREFIX      "ScriptC_"
#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"

#define RS_TYPE_CLASS_SUPER_CLASS_NAME   "android.renderscript.Script.FieldBase"

#define RS_TYPE_ITEM_CLASS_NAME          "Item"

#define RS_TYPE_ITEM_BUFFER_NAME         "mItemArray"
#define RS_TYPE_ITEM_BUFFER_PACKER_NAME  "mIOBuffer"
#define RS_TYPE_ELEMENT_REF_NAME         "mElementCache"

#define RS_EXPORT_VAR_INDEX_PREFIX       "mExportVarIdx_"
#define RS_EXPORT_VAR_PREFIX             "mExportVar_"
#define RS_EXPORT_VAR_ELEM_PREFIX        "mExportVarElem_"
#define RS_EXPORT_VAR_DIM_PREFIX         "mExportVarDim_"
#define RS_EXPORT_VAR_CONST_PREFIX       "const_"

#define RS_ELEM_PREFIX                   "__"

#define RS_FP_PREFIX                     "__rs_fp_"

#define RS_RESOURCE_NAME                 "__rs_resource_name"

#define RS_EXPORT_FUNC_INDEX_PREFIX      "mExportFuncIdx_"
#define RS_EXPORT_FOREACH_INDEX_PREFIX   "mExportForEachIdx_"

#define RS_EXPORT_VAR_ALLOCATION_PREFIX  "mAlloction_"
#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"

namespace slang {

// Some utility function using internal in RSReflection
static bool GetClassNameFromFileName(const std::string &FileName,
                                     std::string &ClassName) {
  ClassName.clear();

  if (FileName.empty() || (FileName == "-"))
    return true;

  ClassName =
      RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str());

  return true;
}

static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
  static const char *MatrixTypeJavaNameMap[] = {
    /* 2x2 */ "Matrix2f",
    /* 3x3 */ "Matrix3f",
    /* 4x4 */ "Matrix4f",
  };
  unsigned Dim = EMT->getDim();

  if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*)))
    return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ];

  slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
  return NULL;
}

static const char *GetVectorAccessor(unsigned Index) {
  static const char *VectorAccessorMap[] = {
    /* 0 */ "x",
    /* 1 */ "y",
    /* 2 */ "z",
    /* 3 */ "w",
  };

  slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
              "Out-of-bound index to access vector member");

  return VectorAccessorMap[Index];
}

static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
  static const char *PrimitiveTypePackerAPINameMap[] = {
    "",         // RSExportPrimitiveType::DataTypeFloat16
    "addF32",   // RSExportPrimitiveType::DataTypeFloat32
    "addF64",   // RSExportPrimitiveType::DataTypeFloat64
    "addI8",    // RSExportPrimitiveType::DataTypeSigned8
    "addI16",   // RSExportPrimitiveType::DataTypeSigned16
    "addI32",   // RSExportPrimitiveType::DataTypeSigned32
    "addI64",   // RSExportPrimitiveType::DataTypeSigned64
    "addU8",    // RSExportPrimitiveType::DataTypeUnsigned8
    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned16
    "addU32",   // RSExportPrimitiveType::DataTypeUnsigned32
    "addU64",   // RSExportPrimitiveType::DataTypeUnsigned64
    "addBoolean",  // RSExportPrimitiveType::DataTypeBoolean

    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned565
    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned5551
    "addU16",   // RSExportPrimitiveType::DataTypeUnsigned4444

    "addMatrix",   // RSExportPrimitiveType::DataTypeRSMatrix2x2
    "addMatrix",   // RSExportPrimitiveType::DataTypeRSMatrix3x3
    "addMatrix",   // RSExportPrimitiveType::DataTypeRSMatrix4x4

    "addObj",   // RSExportPrimitiveType::DataTypeRSElement
    "addObj",   // RSExportPrimitiveType::DataTypeRSType
    "addObj",   // RSExportPrimitiveType::DataTypeRSAllocation
    "addObj",   // RSExportPrimitiveType::DataTypeRSSampler
    "addObj",   // RSExportPrimitiveType::DataTypeRSScript
    "addObj",   // RSExportPrimitiveType::DataTypeRSMesh
    "addObj",   // RSExportPrimitiveType::DataTypeRSPath
    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramFragment
    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramVertex
    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramRaster
    "addObj",   // RSExportPrimitiveType::DataTypeRSProgramStore
    "addObj",   // RSExportPrimitiveType::DataTypeRSFont
  };
  unsigned TypeId = EPT->getType();

  if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))
    return PrimitiveTypePackerAPINameMap[ EPT->getType() ];

  slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
  return NULL;
}

static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      return RSExportPrimitiveType::getRSReflectionType(
          static_cast<const RSExportPrimitiveType*>(ET))->java_name;
    }
    case RSExportType::ExportClassPointer: {
      const RSExportType *PointeeType =
          static_cast<const RSExportPointerType*>(ET)->getPointeeType();

      if (PointeeType->getClass() != RSExportType::ExportClassRecord)
        return "Allocation";
      else
        return PointeeType->getElementName();
    }
    case RSExportType::ExportClassVector: {
      const RSExportVectorType *EVT =
          static_cast<const RSExportVectorType*>(ET);
      std::stringstream VecName;
      VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
              << EVT->getNumElement();
      return VecName.str();
    }
    case RSExportType::ExportClassMatrix: {
      return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
    }
    case RSExportType::ExportClassConstantArray: {
      const RSExportConstantArrayType* CAT =
          static_cast<const RSExportConstantArrayType*>(ET);
      std::string ElementTypeName = GetTypeName(CAT->getElementType());
      if (Brackets) {
        ElementTypeName.append("[]");
      }
      return ElementTypeName;
    }
    case RSExportType::ExportClassRecord: {
      return ET->getElementName() + "."RS_TYPE_ITEM_CLASS_NAME;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }

  return "";
}

static const char *GetTypeNullValue(const RSExportType *ET) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      const RSExportPrimitiveType *EPT =
          static_cast<const RSExportPrimitiveType*>(ET);
      if (EPT->isRSObjectType())
        return "null";
      else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean)
        return "false";
      else
        return "0";
      break;
    }
    case RSExportType::ExportClassPointer:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassMatrix:
    case RSExportType::ExportClassConstantArray:
    case RSExportType::ExportClassRecord: {
      return "null";
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }
  return "";
}

static std::string GetBuiltinElementConstruct(const RSExportType *ET) {
  if (ET->getClass() == RSExportType::ExportClassPrimitive) {
    return std::string("Element.") + ET->getElementName();
  } else if (ET->getClass() == RSExportType::ExportClassVector) {
    const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET);
    if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
      if (EVT->getNumElement() == 2)
        return "Element.F32_2";
      else if (EVT->getNumElement() == 3)
        return "Element.F32_3";
      else if (EVT->getNumElement() == 4)
        return "Element.F32_4";
    } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
      if (EVT->getNumElement() == 4)
        return "Element.U8_4";
    }
  } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
    const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
    switch (EMT->getDim()) {
      case 2: return "Element.MATRIX_2X2";
      case 3: return "Element.MATRIX_3X3";
      case 4: return "Element.MATRIX_4X4";
      default: slangAssert(false && "Unsupported dimension of matrix");
    }
  }
  // RSExportType::ExportClassPointer can't be generated in a struct.

  return "";
}


/********************** Methods to generate script class **********************/
bool RSReflection::genScriptClass(Context &C,
                                  const std::string &ClassName,
                                  std::string &ErrorMsg) {
  if (!C.startClass(Context::AM_Public,
                    false,
                    ClassName,
                    RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
                    ErrorMsg))
    return false;

  genScriptClassConstructor(C);

  // Reflect export variable
  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
           E = mRSContext->export_vars_end();
       I != E;
       I++)
    genExportVariable(C, *I);

  // Reflect export for each functions (only available on ICS+)
  if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
    for (RSContext::const_export_foreach_iterator
             I = mRSContext->export_foreach_begin(),
             E = mRSContext->export_foreach_end();
         I != E; I++)
      genExportForEach(C, *I);
  }

  // Reflect export function
  for (RSContext::const_export_func_iterator
           I = mRSContext->export_funcs_begin(),
           E = mRSContext->export_funcs_end();
       I != E; I++)
    genExportFunction(C, *I);

  C.endClass();

  return true;
}

void RSReflection::genScriptClassConstructor(Context &C) {
  // Provide a simple way to reference this object.
  C.indent() << "private static final String " RS_RESOURCE_NAME " = \""
             << C.getResourceId()
             << "\";" << std::endl;

  // Generate a simple constructor with only a single parameter (the rest
  // can be inferred from information we already have).
  C.indent() << "// Constructor" << std::endl;
  C.startFunction(Context::AM_Public,
                  false,
                  NULL,
                  C.getClassName(),
                  1,
                  "RenderScript", "rs");
  // Call alternate constructor with required parameters.
  // Look up the proper raw bitcode resource id via the context.
  C.indent() << "this(rs," << std::endl;
  C.indent() << "     rs.getApplicationContext().getResources()," << std::endl;
  C.indent() << "     rs.getApplicationContext().getResources()."
                "getIdentifier(" << std::endl;
  C.indent() << "         " RS_RESOURCE_NAME ", \"raw\"," << std::endl;
  C.indent() << "         rs.getApplicationContext().getPackageName()));"
             << std::endl;
  C.endFunction();

  // Alternate constructor (legacy) with 3 original parameters.
  C.startFunction(Context::AM_Public,
                  false,
                  NULL,
                  C.getClassName(),
                  3,
                  "RenderScript", "rs",
                  "Resources", "resources",
                  "int", "id");
  // Call constructor of super class
  C.indent() << "super(rs, resources, id);" << std::endl;

  // If an exported variable has initial value, reflect it

  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
           E = mRSContext->export_vars_end();
       I != E;
       I++) {
    const RSExportVar *EV = *I;
    if (!EV->getInit().isUninit()) {
      genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit());
    } else if (EV->getArraySize()) {
      // Always create an initial zero-init array object.
      C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
                 << GetTypeName(EV->getType(), false) << "["
                 << EV->getArraySize() << "];" << std::endl;
      size_t NumInits = EV->getNumInits();
      const RSExportConstantArrayType *ECAT =
          static_cast<const RSExportConstantArrayType*>(EV->getType());
      const RSExportType *ET = ECAT->getElementType();
      for (size_t i = 0; i < NumInits; i++) {
        std::stringstream Name;
        Name << EV->getName() << "[" << i << "]";
        genInitExportVariable(C, ET, Name.str(), EV->getInitArray(i));
      }
    }
    if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
      genTypeInstance(C, EV->getType());
    }
    genFieldPackerInstance(C, EV->getType());
  }

  for (RSContext::const_export_foreach_iterator
           I = mRSContext->export_foreach_begin(),
           E = mRSContext->export_foreach_end();
       I != E;
       I++) {
    const RSExportForEach *EF = *I;

    const RSExportType *IET = EF->getInType();
    if (IET) {
      genTypeInstanceFromPointer(C, IET);
    }
    const RSExportType *OET = EF->getOutType();
    if (OET) {
      genTypeInstanceFromPointer(C, OET);
    }
  }

  C.endFunction();

  for (std::set<std::string>::iterator I = C.mTypesToCheck.begin(),
                                       E = C.mTypesToCheck.end();
       I != E;
       I++) {
    C.indent() << "private Element " RS_ELEM_PREFIX << *I << ";" << std::endl;
  }

  for (std::set<std::string>::iterator I = C.mFieldPackerTypes.begin(),
                                       E = C.mFieldPackerTypes.end();
       I != E;
       I++) {
    C.indent() << "private FieldPacker " RS_FP_PREFIX << *I << ";" << std::endl;
  }

  return;
}

void RSReflection::genInitBoolExportVariable(Context &C,
                                             const std::string &VarName,
                                             const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");

  C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
  slangAssert((Val.getKind() == clang::APValue::Int) &&
              "Bool type has wrong initial APValue");

  C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
          << ";" << std::endl;

  return;
}

void RSReflection::genInitPrimitiveExportVariable(
      Context &C,
      const std::string &VarName,
      const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");

  C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
  C.out() << RSReflectionBase::genInitValue(Val);
  C.out() << ";" << std::endl;

  return;
}

void RSReflection::genInitExportVariable(Context &C,
                                         const RSExportType *ET,
                                         const std::string &VarName,
                                         const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");

  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      const RSExportPrimitiveType *EPT =
          static_cast<const RSExportPrimitiveType*>(ET);
      if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
        genInitBoolExportVariable(C, VarName, Val);
      } else {
        genInitPrimitiveExportVariable(C, VarName, Val);
      }
      break;
    }
    case RSExportType::ExportClassPointer: {
      if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
        std::cout << "Initializer which is non-NULL to pointer type variable "
                     "will be ignored" << std::endl;
      break;
    }
    case RSExportType::ExportClassVector: {
      const RSExportVectorType *EVT =
          static_cast<const RSExportVectorType*>(ET);
      switch (Val.getKind()) {
        case clang::APValue::Int:
        case clang::APValue::Float: {
          for (unsigned i = 0; i < EVT->getNumElement(); i++) {
            std::string Name =  VarName + "." + GetVectorAccessor(i);
            genInitPrimitiveExportVariable(C, Name, Val);
          }
          break;
        }
        case clang::APValue::Vector: {
          std::stringstream VecName;
          VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
                  << EVT->getNumElement();
          C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
                     << VecName.str() << "();" << std::endl;

          unsigned NumElements =
              std::min(static_cast<unsigned>(EVT->getNumElement()),
                       Val.getVectorLength());
          for (unsigned i = 0; i < NumElements; i++) {
            const clang::APValue &ElementVal = Val.getVectorElt(i);
            std::string Name = VarName + "." + GetVectorAccessor(i);
            genInitPrimitiveExportVariable(C, Name, ElementVal);
          }
          break;
        }
        case clang::APValue::MemberPointer:
        case clang::APValue::Uninitialized:
        case clang::APValue::ComplexInt:
        case clang::APValue::ComplexFloat:
        case clang::APValue::LValue:
        case clang::APValue::Array:
        case clang::APValue::Struct:
        case clang::APValue::Union:
        case clang::APValue::AddrLabelDiff: {
          slangAssert(false && "Unexpected type of value of initializer.");
        }
      }
      break;
    }
    // TODO(zonr): Resolving initializer of a record (and matrix) type variable
    // is complex. It cannot obtain by just simply evaluating the initializer
    // expression.
    case RSExportType::ExportClassMatrix:
    case RSExportType::ExportClassConstantArray:
    case RSExportType::ExportClassRecord: {
#if 0
      unsigned InitIndex = 0;
      const RSExportRecordType *ERT =
          static_cast<const RSExportRecordType*>(ET);

      slangAssert((Val.getKind() == clang::APValue::Vector) &&
          "Unexpected type of initializer for record type variable");

      C.indent() << RS_EXPORT_VAR_PREFIX << VarName
                 << " = new " << ERT->getElementName()
                 <<  "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;

      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
               E = ERT->fields_end();
           I != E;
           I++) {
        const RSExportRecordType::Field *F = *I;
        std::string FieldName = VarName + "." + F->getName();

        if (InitIndex > Val.getVectorLength())
          break;

        genInitPrimitiveExportVariable(C,
                                       FieldName,
                                       Val.getVectorElt(InitIndex++));
      }
#endif
      slangAssert(false && "Unsupported initializer for record/matrix/constant "
                           "array type variable currently");
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }
  return;
}

void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) {
  const RSExportType *ET = EV->getType();

  C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX
             << EV->getName() << " = " << C.getNextExportVarSlot() << ";"
             << std::endl;

  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      genPrimitiveTypeExportVariable(C, EV);
      break;
    }
    case RSExportType::ExportClassPointer: {
      genPointerTypeExportVariable(C, EV);
      break;
    }
    case RSExportType::ExportClassVector: {
      genVectorTypeExportVariable(C, EV);
      break;
    }
    case RSExportType::ExportClassMatrix: {
      genMatrixTypeExportVariable(C, EV);
      break;
    }
    case RSExportType::ExportClassConstantArray: {
      genConstantArrayTypeExportVariable(C, EV);
      break;
    }
    case RSExportType::ExportClassRecord: {
      genRecordTypeExportVariable(C, EV);
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }

  return;
}

void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) {
  C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX
             << EF->getName() << " = " << C.getNextExportFuncSlot() << ";"
             << std::endl;

  // invoke_*()
  Context::ArgTy Args;

  if (EF->hasParam()) {
    for (RSExportFunc::const_param_iterator I = EF->params_begin(),
             E = EF->params_end();
         I != E;
         I++) {
      Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
                                    (*I)->getName()));
    }
  }

  C.startFunction(Context::AM_Public,
                  false,
                  "void",
                  "invoke_" + EF->getName(/*Mangle=*/ false),
                      // We are using un-mangled name since Java
                      // supports method overloading.
                  Args);

  if (!EF->hasParam()) {
    C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");"
               << std::endl;
  } else {
    const RSExportRecordType *ERT = EF->getParamPacketType();
    std::string FieldPackerName = EF->getName() + "_fp";

    if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
      genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());

    C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", "
               << FieldPackerName << ");" << std::endl;
  }

  C.endFunction();
  return;
}

void RSReflection::genExportForEach(Context &C, const RSExportForEach *EF) {
  if (EF->isDummyRoot()) {
    // Skip reflection for dummy root() kernels. Note that we have to
    // advance the next slot number for ForEach, however.
    C.indent() << "//private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX
               << EF->getName() << " = " << C.getNextExportForEachSlot() << ";"
               << std::endl;
    return;
  }

  C.indent() << "private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX
             << EF->getName() << " = " << C.getNextExportForEachSlot() << ";"
             << std::endl;

  // forEach_*()
  Context::ArgTy Args;

  slangAssert(EF->getNumParameters() > 0 || EF->hasReturn());

  if (EF->hasIn())
    Args.push_back(std::make_pair("Allocation", "ain"));
  if (EF->hasOut() || EF->hasReturn())
    Args.push_back(std::make_pair("Allocation", "aout"));

  const RSExportRecordType *ERT = EF->getParamPacketType();
  if (ERT) {
    for (RSExportForEach::const_param_iterator I = EF->params_begin(),
             E = EF->params_end();
         I != E;
         I++) {
      Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
                                    (*I)->getName()));
    }
  }

  const RSExportType *IET = EF->getInType();
  const RSExportType *OET = EF->getOutType();

  if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
      int signature = 0;
      C.startFunction(Context::AM_Public,
                      false,
                      "Script.KernelID",
                      "getKernelID_" + EF->getName(),
                      0);

      if (IET)
          signature |= 1;
      if (OET)
          signature |= 2;

      //TODO: add element checking
      C.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
                 << EF->getName() << ", " << signature << ", null, null);"
                 << std::endl;

      C.endFunction();
  }

  C.startFunction(Context::AM_Public,
                  false,
                  "void",
                  "forEach_" + EF->getName(),
                  Args);

  if (IET) {
    genTypeCheck(C, IET, "ain");
  }
  if (OET) {
    genTypeCheck(C, OET, "aout");
  }

  if (EF->hasIn() && (EF->hasOut() || EF->hasReturn())) {
    C.indent() << "// Verify dimensions" << std::endl;
    C.indent() << "Type tIn = ain.getType();" << std::endl;
    C.indent() << "Type tOut = aout.getType();" << std::endl;
    C.indent() << "if ((tIn.getCount() != tOut.getCount()) ||" << std::endl;
    C.indent() << "    (tIn.getX() != tOut.getX()) ||" << std::endl;
    C.indent() << "    (tIn.getY() != tOut.getY()) ||" << std::endl;
    C.indent() << "    (tIn.getZ() != tOut.getZ()) ||" << std::endl;
    C.indent() << "    (tIn.hasFaces() != tOut.hasFaces()) ||" << std::endl;
    C.indent() << "    (tIn.hasMipmaps() != tOut.hasMipmaps())) {" << std::endl;
    C.indent() << "    throw new RSRuntimeException(\"Dimension mismatch "
               << "between input and output parameters!\");";
    C.out()    << std::endl;
    C.indent() << "}" << std::endl;
  }

  std::string FieldPackerName = EF->getName() + "_fp";
  if (ERT) {
    if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) {
      genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
    }
  }
  C.indent() << "forEach("RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName();

  if (EF->hasIn())
    C.out() << ", ain";
  else
    C.out() << ", null";

  if (EF->hasOut() || EF->hasReturn())
    C.out() << ", aout";
  else
    C.out() << ", null";

  if (EF->hasUsrData())
    C.out() << ", " << FieldPackerName;
  else
    C.out() << ", null";

  C.out() << ");" << std::endl;

  C.endFunction();
  return;
}

void RSReflection::genTypeInstanceFromPointer(Context &C,
                                              const RSExportType *ET) {
  if (ET->getClass() == RSExportType::ExportClassPointer) {
    // For pointer parameters to original forEach kernels.
    const RSExportPointerType *EPT =
        static_cast<const RSExportPointerType*>(ET);
    genTypeInstance(C, EPT->getPointeeType());
  } else {
    // For handling pass-by-value kernel parameters.
    genTypeInstance(C, ET);
  }
}

void RSReflection::genTypeInstance(Context &C,
                                   const RSExportType *ET) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassConstantArray: {
      std::string TypeName = ET->getElementName();
      if (C.addTypeNameForElement(TypeName)) {
        C.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
                   << "(rs);" << std::endl;
      }
      break;
    }

    case RSExportType::ExportClassRecord: {
      std::string ClassName = ET->getElementName();
      if (C.addTypeNameForElement(ClassName)) {
        C.indent() << RS_ELEM_PREFIX << ClassName << " = " << ClassName <<
                      ".createElement(rs);" << std::endl;
      }
      break;
    }

    default:
      break;
  }
}

void RSReflection::genFieldPackerInstance(Context &C,
                                          const RSExportType *ET) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassConstantArray:
    case RSExportType::ExportClassRecord: {
      std::string TypeName = ET->getElementName();
      C.addTypeNameForFieldPacker(TypeName);
      break;
    }

    default:
      break;
  }
}

void RSReflection::genTypeCheck(Context &C,
                                const RSExportType *ET,
                                const char *VarName) {
  C.indent() << "// check " << VarName << std::endl;

  if (ET->getClass() == RSExportType::ExportClassPointer) {
    const RSExportPointerType *EPT =
        static_cast<const RSExportPointerType*>(ET);
    ET = EPT->getPointeeType();
  }

  std::string TypeName;

  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassRecord: {
      TypeName = ET->getElementName();
      break;
    }

    default:
      break;
  }

  if (!TypeName.empty()) {
    C.indent() << "if (!" << VarName
               << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
               << TypeName << ")) {" << std::endl;
    C.indent() << "    throw new RSRuntimeException(\"Type mismatch with "
               << TypeName << "!\");" << std::endl;
    C.indent() << "}" << std::endl;
  }

  return;
}


void RSReflection::genPrimitiveTypeExportVariable(
    Context &C,
    const RSExportVar *EV) {
  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive)
              && "Variable should be type of primitive here");

  const RSExportPrimitiveType *EPT =
      static_cast<const RSExportPrimitiveType*>(EV->getType());
  std::string TypeName = GetTypeName(EPT);
  std::string VarName = EV->getName();

  genPrivateExportVariable(C, TypeName, EV->getName());

  if (EV->isConst()) {
    C.indent() << "public final static " << TypeName
               << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
    const clang::APValue &Val = EV->getInit();
    C.out() << RSReflectionBase::genInitValue(Val, EPT->getType() ==
        RSExportPrimitiveType::DataTypeBoolean) << ";" << std::endl;
  } else {
    // set_*()
    // This must remain synchronized, since multiple Dalvik threads may
    // be calling setters.
    C.startFunction(Context::AM_PublicSynchronized,
                    false,
                    "void",
                    "set_" + VarName,
                    1,
                    TypeName.c_str(), "v");
    if ((EPT->getSize() < 4) || EV->isUnsigned()) {
      // We create/cache a per-type FieldPacker. This allows us to reuse the
      // validation logic (for catching negative inputs from Dalvik, as well
      // as inputs that are too large to be represented in the unsigned type).
      // Sub-integer types are also handled specially here, so that we don't
      // overwrite bytes accidentally.
      std::string ElemName = EPT->getElementName();
      std::string FPName;
      FPName = RS_FP_PREFIX + ElemName;
      C.indent() << "if (" << FPName << "!= null) {"
                 << std::endl;
      C.incIndentLevel();
      C.indent() << FPName << ".reset();" << std::endl;
      C.decIndentLevel();
      C.indent() << "} else {" << std::endl;
      C.incIndentLevel();
      C.indent() << FPName << " = new FieldPacker("
                 << EPT->getSize() << ");" << std::endl;
      C.decIndentLevel();
      C.indent() << "}" << std::endl;

      genPackVarOfType(C, EPT, "v", FPName.c_str());
      C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << VarName
                 << ", " << FPName << ");" << std::endl;
    } else {
      C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << VarName
                 << ", v);" << std::endl;
    }

    // Dalvik update comes last, since the input may be invalid (and hence
    // throw an exception).
    C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;" << std::endl;

    C.endFunction();
  }

  genGetExportVariable(C, TypeName, VarName);
  genGetFieldID(C, VarName);
  return;
}

void RSReflection::genPointerTypeExportVariable(Context &C,
                                                const RSExportVar *EV) {
  const RSExportType *ET = EV->getType();
  const RSExportType *PointeeType;

  slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
              "Variable should be type of pointer here");

  PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
  std::string TypeName = GetTypeName(ET);
  std::string VarName = EV->getName();

  genPrivateExportVariable(C, TypeName, VarName);

  // bind_*()
  C.startFunction(Context::AM_Public,
                  false,
                  "void",
                  "bind_" + VarName,
                  1,
                  TypeName.c_str(), "v");

  C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;" << std::endl;
  C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX
             << VarName << ");" << std::endl;

  if (PointeeType->getClass() == RSExportType::ExportClassRecord)
    C.indent() << "else bindAllocation(v.getAllocation(), "
        RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");"
               << std::endl;
  else
    C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX
               << VarName << ");" << std::endl;

  C.endFunction();

  genGetExportVariable(C, TypeName, VarName);
  return;
}

void RSReflection::genVectorTypeExportVariable(Context &C,
                                               const RSExportVar *EV) {
  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
              "Variable should be type of vector here");

  std::string TypeName = GetTypeName(EV->getType());
  std::string VarName = EV->getName();

  genPrivateExportVariable(C, TypeName, VarName);
  genSetExportVariable(C, TypeName, EV);
  genGetExportVariable(C, TypeName, VarName);
  genGetFieldID(C, VarName);
  return;
}

void RSReflection::genMatrixTypeExportVariable(Context &C,
                                               const RSExportVar *EV) {
  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
              "Variable should be type of matrix here");

    const RSExportType *ET = EV->getType();
  std::string TypeName = GetTypeName(ET);
  std::string VarName = EV->getName();

  genPrivateExportVariable(C, TypeName, VarName);

  // set_*()
  if (!EV->isConst()) {
    const char *FieldPackerName = "fp";
    C.startFunction(Context::AM_PublicSynchronized,
                    false,
                    "void",
                    "set_" + VarName,
                    1,
                    TypeName.c_str(), "v");
    C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;" << std::endl;

    if (genCreateFieldPacker(C, ET, FieldPackerName))
      genPackVarOfType(C, ET, "v", FieldPackerName);
    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
               << FieldPackerName << ");" << std::endl;

    C.endFunction();
  }

  genGetExportVariable(C, TypeName, VarName);
  genGetFieldID(C, VarName);
  return;
}

void RSReflection::genConstantArrayTypeExportVariable(
    Context &C,
    const RSExportVar *EV) {
  slangAssert((EV->getType()->getClass() ==
               RSExportType::ExportClassConstantArray) &&
              "Variable should be type of constant array here");

  std::string TypeName = GetTypeName(EV->getType());
  std::string VarName = EV->getName();

  genPrivateExportVariable(C, TypeName, VarName);
  genSetExportVariable(C, TypeName, EV);
  genGetExportVariable(C, TypeName, VarName);
  genGetFieldID(C, VarName);
  return;
}

void RSReflection::genRecordTypeExportVariable(Context &C,
                                               const RSExportVar *EV) {
  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
              "Variable should be type of struct here");

  std::string TypeName = GetTypeName(EV->getType());
  std::string VarName = EV->getName();

  genPrivateExportVariable(C, TypeName, VarName);
  genSetExportVariable(C, TypeName, EV);
  genGetExportVariable(C, TypeName, VarName);
  genGetFieldID(C, VarName);
  return;
}

void RSReflection::genPrivateExportVariable(Context &C,
                                            const std::string &TypeName,
                                            const std::string &VarName) {
  C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
             << VarName << ";" << std::endl;
  return;
}

void RSReflection::genSetExportVariable(Context &C,
                                        const std::string &TypeName,
                                        const RSExportVar *EV) {
  if (!EV->isConst()) {
    const char *FieldPackerName = "fp";
    std::string VarName = EV->getName();
    const RSExportType *ET = EV->getType();
    C.startFunction(Context::AM_PublicSynchronized,
                    false,
                    "void",
                    "set_" + VarName,
                    1,
                    TypeName.c_str(), "v");
    C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;" << std::endl;

    if (genCreateFieldPacker(C, ET, FieldPackerName))
      genPackVarOfType(C, ET, "v", FieldPackerName);

    if (mRSContext->getTargetAPI() < SLANG_JB_TARGET_API) {
      // Legacy apps must use the old setVar() without Element/dim components.
      C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << VarName
                 << ", " << FieldPackerName << ");" << std::endl;
    } else {
      // We only have support for one-dimensional array reflection today,
      // but the entry point (i.e. setVar()) takes an array of dimensions.
      C.indent() << "int []__dimArr = new int[1];" << std::endl;
      C.indent() << "__dimArr[0] = " << ET->getSize() << ";" << std::endl;
      C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
                 << FieldPackerName << ", " RS_ELEM_PREFIX
                 << ET->getElementName() << ", __dimArr);" << std::endl;
    }

    C.endFunction();
  }
  return;
}

void RSReflection::genGetExportVariable(Context &C,
                                        const std::string &TypeName,
                                        const std::string &VarName) {
  C.startFunction(Context::AM_Public,
                  false,
                  TypeName.c_str(),
                  "get_" + VarName,
                  0);

  C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl;

  C.endFunction();
}

void RSReflection::genGetFieldID(Context &C, const std::string &VarName) {
  // We only generate getFieldID_*() for non-Pointer (bind) types.
  if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
    C.startFunction(Context::AM_Public,
                    false,
                    "Script.FieldID",
                    "getFieldID_" + VarName,
                    0);

    C.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
               << VarName << ", null);" << std::endl;

    C.endFunction();
  }
}

/******************* Methods to generate script class /end *******************/

bool RSReflection::genCreateFieldPacker(Context &C,
                                        const RSExportType *ET,
                                        const char *FieldPackerName) {
  size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
  if (AllocSize > 0)
    C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
               << AllocSize << ");" << std::endl;
  else
    return false;
  return true;
}

void RSReflection::genPackVarOfType(Context &C,
                                    const RSExportType *ET,
                                    const char *VarName,
                                    const char *FieldPackerName) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive:
    case RSExportType::ExportClassVector: {
      C.indent() << FieldPackerName << "."
                 << GetPackerAPIName(
                     static_cast<const RSExportPrimitiveType*>(ET))
                 << "(" << VarName << ");" << std::endl;
      break;
    }
    case RSExportType::ExportClassPointer: {
      // Must reflect as type Allocation in Java
      const RSExportType *PointeeType =
          static_cast<const RSExportPointerType*>(ET)->getPointeeType();

      if (PointeeType->getClass() != RSExportType::ExportClassRecord)
        C.indent() << FieldPackerName << ".addI32(" << VarName
                   << ".getPtr());" << std::endl;
      else
        C.indent() << FieldPackerName << ".addI32(" << VarName
                   << ".getAllocation().getPtr());" << std::endl;
      break;
    }
    case RSExportType::ExportClassMatrix: {
      C.indent() << FieldPackerName << ".addMatrix(" << VarName << ");"
                 << std::endl;
      break;
    }
    case RSExportType::ExportClassConstantArray: {
      const RSExportConstantArrayType *ECAT =
          static_cast<const RSExportConstantArrayType *>(ET);

      // TODO(zonr): more elegant way. Currently, we obtain the unique index
      //             variable (this method involves recursive call which means
      //             we may have more than one level loop, therefore we can't
      //             always use the same index variable name here) name given
      //             in the for-loop from counting the '.' in @VarName.
      unsigned Level = 0;
      size_t LastDotPos = 0;
      std::string ElementVarName(VarName);

      while (LastDotPos != std::string::npos) {
        LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
        Level++;
      }
      std::string IndexVarName("ct");
      IndexVarName.append(llvm::utostr_32(Level));

      C.indent() << "for (int " << IndexVarName << " = 0; " <<
                          IndexVarName << " < " << ECAT->getSize() << "; " <<
                          IndexVarName << "++)";
      C.startBlock();

      ElementVarName.append("[" + IndexVarName + "]");
      genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
                       FieldPackerName);

      C.endBlock();
      break;
    }
    case RSExportType::ExportClassRecord: {
      const RSExportRecordType *ERT =
          static_cast<const RSExportRecordType*>(ET);
      // Relative pos from now on in field packer
      unsigned Pos = 0;

      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
               E = ERT->fields_end();
           I != E;
           I++) {
        const RSExportRecordType::Field *F = *I;
        std::string FieldName;
        size_t FieldOffset = F->getOffsetInParent();
        size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
        size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());

        if (VarName != NULL)
          FieldName = VarName + ("." + F->getName());
        else
          FieldName = F->getName();

        if (FieldOffset > Pos)
          C.indent() << FieldPackerName << ".skip("
                     << (FieldOffset - Pos) << ");" << std::endl;

        genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);

        // There is padding in the field type
        if (FieldAllocSize > FieldStoreSize)
            C.indent() << FieldPackerName << ".skip("
                       << (FieldAllocSize - FieldStoreSize)
                       << ");" << std::endl;

          Pos = FieldOffset + FieldAllocSize;
      }

      // There maybe some padding after the struct
      if (RSExportType::GetTypeAllocSize(ERT) > Pos)
        C.indent() << FieldPackerName << ".skip("
                   << RSExportType::GetTypeAllocSize(ERT) - Pos << ");"
                   << std::endl;
      break;
    }
    default: {
      slangAssert(false && "Unknown class of type");
    }
  }

  return;
}

void RSReflection::genAllocateVarOfType(Context &C,
                                        const RSExportType *T,
                                        const std::string &VarName) {
  switch (T->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      // Primitive type like int in Java has its own storage once it's declared.
      //
      // FIXME: Should we allocate storage for RS object?
      // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
      //  C.indent() << VarName << " = new " << GetTypeName(T) << "();"
      //             << std::endl;
      break;
    }
    case RSExportType::ExportClassPointer: {
      // Pointer type is an instance of Allocation or a TypeClass whose value is
      // expected to be assigned by programmer later in Java program. Therefore
      // we don't reflect things like [VarName] = new Allocation();
      C.indent() << VarName << " = null;" << std::endl;
      break;
    }
    case RSExportType::ExportClassConstantArray: {
      const RSExportConstantArrayType *ECAT =
          static_cast<const RSExportConstantArrayType *>(T);
      const RSExportType *ElementType = ECAT->getElementType();

      C.indent() << VarName << " = new " << GetTypeName(ElementType)
                 << "[" << ECAT->getSize() << "];" << std::endl;

      // Primitive type element doesn't need allocation code.
      if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
        C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; "
                            "$ct++)";
        C.startBlock();

        std::string ElementVarName(VarName);
        ElementVarName.append("[$ct]");
        genAllocateVarOfType(C, ElementType, ElementVarName);

        C.endBlock();
      }
      break;
    }
    case RSExportType::ExportClassVector:
    case RSExportType::ExportClassMatrix:
    case RSExportType::ExportClassRecord: {
      C.indent() << VarName << " = new " << GetTypeName(T) << "();"
                 << std::endl;
      break;
    }
  }
  return;
}

void RSReflection::genNewItemBufferIfNull(Context &C,
                                          const char *Index) {
  C.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME " == null) "
                  RS_TYPE_ITEM_BUFFER_NAME " = "
                    "new " RS_TYPE_ITEM_CLASS_NAME
                      "[getType().getX() /* count */];"
             << std::endl;
  if (Index != NULL)
    C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) "
                    RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = "
                      "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
  return;
}

void RSReflection::genNewItemBufferPackerIfNull(Context &C) {
  C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " == null) "
                  RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
                    "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
                      ".sizeof * getType().getX()/* count */"
                        ");" << std::endl;
  return;
}

/********************** Methods to generate type class  **********************/
bool RSReflection::genTypeClass(Context &C,
                                const RSExportRecordType *ERT,
                                std::string &ErrorMsg) {
  std::string ClassName = ERT->getElementName();

  if (!C.startClass(Context::AM_Public,
                    false,
                    ClassName,
                    RS_TYPE_CLASS_SUPER_CLASS_NAME,
                    ErrorMsg))
    return false;

  mGeneratedFileNames->push_back(ClassName);

  genTypeItemClass(C, ERT);

  // Declare item buffer and item buffer packer
  C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]"
      ";" << std::endl;
  C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";"
             << std::endl;
  C.indent() << "private static java.lang.ref.WeakReference<Element> "
             RS_TYPE_ELEMENT_REF_NAME
             " = new java.lang.ref.WeakReference<Element>(null);" << std::endl;

  genTypeClassConstructor(C, ERT);
  genTypeClassCopyToArrayLocal(C, ERT);
  genTypeClassCopyToArray(C, ERT);
  genTypeClassItemSetter(C, ERT);
  genTypeClassItemGetter(C, ERT);
  genTypeClassComponentSetter(C, ERT);
  genTypeClassComponentGetter(C, ERT);
  genTypeClassCopyAll(C, ERT);
  genTypeClassResize(C);

  C.endClass();

  C.resetFieldIndex();
  C.clearFieldIndexMap();

  return true;
}

void RSReflection::genTypeItemClass(Context &C,
                                    const RSExportRecordType *ERT) {
  C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
  C.startBlock();

  C.indent() << "public static final int sizeof = "
             << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl;

  // Member elements
  C.out() << std::endl;
  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
           FE = ERT->fields_end();
       FI != FE;
       FI++) {
    C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
               << ";" << std::endl;
  }

  // Constructor
  C.out() << std::endl;
  C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
  C.startBlock();

  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
           FE = ERT->fields_end();
       FI != FE;
       FI++) {
    const RSExportRecordType::Field *F = *FI;
    genAllocateVarOfType(C, F->getType(), F->getName());
  }

  // end Constructor
  C.endBlock();

  // end Item class
  C.endBlock();

  return;
}

void RSReflection::genTypeClassConstructor(Context &C,
                                           const RSExportRecordType *ERT) {
  const char *RenderScriptVar = "rs";

  C.startFunction(Context::AM_Public,
                  true,
                  "Element",
                  "createElement",
                  1,
                  "RenderScript", RenderScriptVar);

  // TODO(all): Fix weak-refs + multi-context issue.
  // C.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
  //            << ".get();" << std::endl;
  // C.indent() << "if (e != null) return e;" << std::endl;
  genBuildElement(C, "eb", ERT, RenderScriptVar, /* IsInline = */true);
  C.indent() << "return eb.create();" << std::endl;
  // C.indent() << "e = eb.create();" << std::endl;
  // C.indent() << RS_TYPE_ELEMENT_REF_NAME
  //            << " = new java.lang.ref.WeakReference<Element>(e);"
  //            << std::endl;
  // C.indent() << "return e;" << std::endl;
  C.endFunction();


  // private with element
  C.startFunction(Context::AM_Private,
                  false,
                  NULL,
                  C.getClassName(),
                  1,
                  "RenderScript", RenderScriptVar);
  C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
  C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
  C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
             << std::endl;
  C.endFunction();

  // 1D without usage
  C.startFunction(Context::AM_Public,
                  false,
                  NULL,
                  C.getClassName(),
                  2,
                  "RenderScript", RenderScriptVar,
                  "int", "count");

  C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
  C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
  C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
             << std::endl;
  // Call init() in super class
  C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl;
  C.endFunction();

  // 1D with usage
  C.startFunction(Context::AM_Public,
                  false,
                  NULL,
                  C.getClassName(),
                  3,
                  "RenderScript", RenderScriptVar,
                  "int", "count",
                  "int", "usages");

  C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
  C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
  C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
             << std::endl;
  // Call init() in super class
  C.indent() << "init(" << RenderScriptVar << ", count, usages);" << std::endl;
  C.endFunction();


  // create1D with usage
  C.startFunction(Context::AM_Public,
                  true,
                  C.getClassName().c_str(),
                  "create1D",
                  3,
                  "RenderScript", RenderScriptVar,
                  "int", "dimX",
                  "int", "usages");
  C.indent() << C.getClassName() << " obj = new " << C.getClassName() << "("
             << RenderScriptVar << ");" << std::endl;
  C.indent() << "obj.mAllocation = Allocation.createSized("
                "rs, obj.mElement, dimX, usages);" << std::endl;
  C.indent() << "return obj;" << std::endl;
  C.endFunction();

  // create1D without usage
  C.startFunction(Context::AM_Public,
                  true,
                  C.getClassName().c_str(),
                  "create1D",
                  2,
                  "RenderScript", RenderScriptVar,
                  "int", "dimX");
  C.indent() << "return create1D(" << RenderScriptVar
             << ", dimX, Allocation.USAGE_SCRIPT);" << std::endl;
  C.endFunction();


  // create2D without usage
  C.startFunction(Context::AM_Public,
                  true,
                  C.getClassName().c_str(),
                  "create2D",
                  3,
                  "RenderScript", RenderScriptVar,
                  "int", "dimX",
                  "int", "dimY");
  C.indent() << "return create2D(" << RenderScriptVar
             << ", dimX, dimY, Allocation.USAGE_SCRIPT);" << std::endl;
  C.endFunction();

  // create2D with usage
  C.startFunction(Context::AM_Public,
                  true,
                  C.getClassName().c_str(),
                  "create2D",
                  4,
                  "RenderScript", RenderScriptVar,
                  "int", "dimX",
                  "int", "dimY",
                  "int", "usages");

  C.indent() << C.getClassName() << " obj = new " << C.getClassName() << "("
             << RenderScriptVar << ");" << std::endl;
  C.indent() << "Type.Builder b = new Type.Builder(rs, obj.mElement);"
             << std::endl;
  C.indent() << "b.setX(dimX);" << std::endl;
  C.indent() << "b.setY(dimY);" << std::endl;
  C.indent() << "Type t = b.create();" << std::endl;
  C.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);"
             << std::endl;
  C.indent() << "return obj;" << std::endl;
  C.endFunction();


  // createTypeBuilder
  C.startFunction(Context::AM_Public,
                  true,
                  "Type.Builder",
                  "createTypeBuilder",
                  1,
                  "RenderScript", RenderScriptVar);
  C.indent() << "Element e = createElement(" << RenderScriptVar << ");"
             << std::endl;
  C.indent() << "return new Type.Builder(rs, e);" << std::endl;
  C.endFunction();

  // createCustom with usage
  C.startFunction(Context::AM_Public,
                  true,
                  C.getClassName().c_str(),
                  "createCustom",
                  3,
                  "RenderScript", RenderScriptVar,
                  "Type.Builder", "tb",
                  "int", "usages");
  C.indent() << C.getClassName() << " obj = new " << C.getClassName() << "("
             << RenderScriptVar << ");" << std::endl;
  C.indent() << "Type t = tb.create();" << std::endl;
  C.indent() << "if (t.getElement() != obj.mElement) {" << std::endl;
  C.indent() << "    throw new RSIllegalArgumentException("
                "\"Type.Builder did not match expected element type.\");"
             << std::endl;
  C.indent() << "}" << std::endl;
  C.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);"
             << std::endl;
  C.indent() << "return obj;" << std::endl;
  C.endFunction();
}


void RSReflection::genTypeClassCopyToArray(Context &C,
                                           const RSExportRecordType *ERT) {
  C.startFunction(Context::AM_Private,
                  false,
                  "void",
                  "copyToArray",
                  2,
                  RS_TYPE_ITEM_CLASS_NAME, "i",
                  "int", "index");

  genNewItemBufferPackerIfNull(C);
  C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
                ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
             << std::endl;

  C.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
                ");" << std::endl;

  C.endFunction();
  return;
}

void RSReflection::genTypeClassCopyToArrayLocal(Context &C,
                                                const RSExportRecordType *ERT) {
  C.startFunction(Context::AM_Private,
                  false,
                  "void",
                  "copyToArrayLocal",
                  2,
                  RS_TYPE_ITEM_CLASS_NAME, "i",
                  "FieldPacker", "fp");

  genPackVarOfType(C, ERT, "i", "fp");

  C.endFunction();
  return;
}

void RSReflection::genTypeClassItemSetter(Context &C,
                                          const RSExportRecordType *ERT) {
  C.startFunction(Context::AM_PublicSynchronized,
                  false,
                  "void",
                  "set",
                  3,
                  RS_TYPE_ITEM_CLASS_NAME, "i",
                  "int", "index",
                  "boolean", "copyNow");
  genNewItemBufferIfNull(C, NULL);
  C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl;

  C.indent() << "if (copyNow) ";
  C.startBlock();

  C.indent() << "copyToArray(i, index);" << std::endl;
  C.indent() << "FieldPacker fp = new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
                ".sizeof);" << std::endl;
  C.indent() << "copyToArrayLocal(i, fp);" << std::endl;
  C.indent() << "mAllocation.setFromFieldPacker(index, fp);" << std::endl;

  // End of if (copyNow)
  C.endBlock();

  C.endFunction();
  return;
}

void RSReflection::genTypeClassItemGetter(Context &C,
                                          const RSExportRecordType *ERT) {
  C.startFunction(Context::AM_PublicSynchronized,
                  false,
                  RS_TYPE_ITEM_CLASS_NAME,
                  "get",
                  1,
                  "int", "index");
  C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;"
             << std::endl;
  C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl;
  C.endFunction();
  return;
}

void RSReflection::genTypeClassComponentSetter(Context &C,
                                               const RSExportRecordType *ERT) {
  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
           FE = ERT->fields_end();
       FI != FE;
       FI++) {
    const RSExportRecordType::Field *F = *FI;
    size_t FieldOffset = F->getOffsetInParent();
    size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
    unsigned FieldIndex = C.getFieldIndex(F);

    C.startFunction(Context::AM_PublicSynchronized,
                    false,
                    "void",
                    "set_" + F->getName(), 3,
                    "int", "index",
                    GetTypeName(F->getType()).c_str(), "v",
                    "boolean", "copyNow");
    genNewItemBufferPackerIfNull(C);
    genNewItemBufferIfNull(C, "index");
    C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
               << " = v;" << std::endl;

    C.indent() << "if (copyNow) ";
    C.startBlock();

    if (FieldOffset > 0)
      C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
                    ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + "
                 << FieldOffset << ");" << std::endl;
    else
      C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
                    ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
                 << std::endl;
    genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);

    C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");"
               << std::endl;
    genPackVarOfType(C, F->getType(), "v", "fp");
    C.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
               << ", fp);"
               << std::endl;

    // End of if (copyNow)
    C.endBlock();

    C.endFunction();
  }
  return;
}

void RSReflection::genTypeClassComponentGetter(Context &C,
                                               const RSExportRecordType *ERT) {
  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
           FE = ERT->fields_end();
       FI != FE;
       FI++) {
    const RSExportRecordType::Field *F = *FI;
    C.startFunction(Context::AM_PublicSynchronized,
                    false,
                    GetTypeName(F->getType()).c_str(),
                    "get_" + F->getName(),
                    1,
                    "int", "index");
    C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return "
               << GetTypeNullValue(F->getType()) << ";" << std::endl;
    C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
               << ";" << std::endl;
    C.endFunction();
  }
  return;
}

void RSReflection::genTypeClassCopyAll(Context &C,
                                       const RSExportRecordType *ERT) {
  C.startFunction(Context::AM_PublicSynchronized, false, "void", "copyAll", 0);

  C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)"
                  " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);"
             << std::endl;
  C.indent() << "mAllocation.setFromFieldPacker(0, "
                  RS_TYPE_ITEM_BUFFER_PACKER_NAME");"
             << std::endl;

  C.endFunction();
  return;
}

void RSReflection::genTypeClassResize(Context &C) {
  C.startFunction(Context::AM_PublicSynchronized,
                  false,
                  "void",
                  "resize",
                  1,
                  "int", "newSize");

  C.indent() << "if (mItemArray != null) ";
  C.startBlock();
  C.indent() << "int oldSize = mItemArray.length;" << std::endl;
  C.indent() << "int copySize = Math.min(oldSize, newSize);" << std::endl;
  C.indent() << "if (newSize == oldSize) return;" << std::endl;
  C.indent() << "Item ni[] = new Item[newSize];" << std::endl;
  C.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);"
             << std::endl;
  C.indent() << "mItemArray = ni;" << std::endl;
  C.endBlock();
  C.indent() << "mAllocation.resize(newSize);" << std::endl;

  C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " != null) "
                  RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
                    "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
                      ".sizeof * getType().getX()/* count */"
                        ");" << std::endl;

  C.endFunction();
  return;
}

/******************** Methods to generate type class /end ********************/

/********** Methods to create Element in Java of given record type ***********/
void RSReflection::genBuildElement(Context &C,
                                   const char *ElementBuilderName,
                                   const RSExportRecordType *ERT,
                                   const char *RenderScriptVar,
                                   bool IsInline) {
  C.indent() << "Element.Builder " << ElementBuilderName << " = "
      "new Element.Builder(" << RenderScriptVar << ");" << std::endl;

  // eb.add(...)
  genAddElementToElementBuilder(C,
                                ERT,
                                "",
                                ElementBuilderName,
                                RenderScriptVar,
                                /* ArraySize = */0);

  if (!IsInline)
    C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
  return;
}

#define EB_ADD(x) do {                                              \
  C.indent() << ElementBuilderName                                  \
             << ".add(" << x << ", \"" << VarName << "\"";  \
  if (ArraySize > 0)                                                \
    C.out() << ", " << ArraySize;                                   \
  C.out() << ");" << std::endl;                                     \
  C.incFieldIndex();                                                \
} while (false)

void RSReflection::genAddElementToElementBuilder(Context &C,
                                                 const RSExportType *ET,
                                                 const std::string &VarName,
                                                 const char *ElementBuilderName,
                                                 const char *RenderScriptVar,
                                                 unsigned ArraySize) {
  std::string ElementConstruct = GetBuiltinElementConstruct(ET);

  if (ElementConstruct != "") {
    EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
  } else {
    if ((ET->getClass() == RSExportType::ExportClassPrimitive) ||
        (ET->getClass() == RSExportType::ExportClassVector)) {
      const RSExportPrimitiveType *EPT =
          static_cast<const RSExportPrimitiveType*>(ET);
      const char *DataTypeName =
          RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
      int Size = (ET->getClass() == RSExportType::ExportClassVector) ?
          static_cast<const RSExportVectorType*>(ET)->getNumElement() :
          1;

      if (EPT->getClass() == RSExportType::ExportClassPrimitive) {
        // Element.createUser()
        EB_ADD("Element.createUser(" << RenderScriptVar
                                     << ", Element.DataType."
                                     << DataTypeName << ")");
      } else {
        slangAssert((ET->getClass() == RSExportType::ExportClassVector) &&
                    "Unexpected type.");
        EB_ADD("Element.createVector(" << RenderScriptVar
                                       << ", Element.DataType."
                                       << DataTypeName << ", "
                                       << Size << ")");
      }
#ifndef NDEBUG
    } else if (ET->getClass() == RSExportType::ExportClassPointer) {
      // Pointer type variable should be resolved in
      // GetBuiltinElementConstruct()
      slangAssert(false && "??");
    } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
      // Matrix type variable should be resolved
      // in GetBuiltinElementConstruct()
      slangAssert(false && "??");
#endif
    } else if (ET->getClass() == RSExportType::ExportClassConstantArray) {
      const RSExportConstantArrayType *ECAT =
          static_cast<const RSExportConstantArrayType *>(ET);

      const RSExportType *ElementType = ECAT->getElementType();
      if (ElementType->getClass() != RSExportType::ExportClassRecord) {
        genAddElementToElementBuilder(C,
                                      ECAT->getElementType(),
                                      VarName,
                                      ElementBuilderName,
                                      RenderScriptVar,
                                      ECAT->getSize());
      } else {
        std::string NewElementBuilderName(ElementBuilderName);
        NewElementBuilderName.append(1, '_');

        genBuildElement(C,
                        NewElementBuilderName.c_str(),
                        static_cast<const RSExportRecordType*>(ElementType),
                        RenderScriptVar,
                        /* IsInline = */true);
        ArraySize = ECAT->getSize();
        EB_ADD(NewElementBuilderName << ".create()");
      }
    } else if (ET->getClass() == RSExportType::ExportClassRecord) {
      // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
      //
      // TODO(zonr): Generalize these two function such that there's no
      //             duplicated codes.
      const RSExportRecordType *ERT =
          static_cast<const RSExportRecordType*>(ET);
      int Pos = 0;    // relative pos from now on

      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
               E = ERT->fields_end();
           I != E;
           I++) {
        const RSExportRecordType::Field *F = *I;
        std::string FieldName;
        int FieldOffset = F->getOffsetInParent();
        int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
        int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());

        if (!VarName.empty())
          FieldName = VarName + "." + F->getName();
        else
          FieldName = F->getName();

        // Alignment
        genAddPaddingToElementBuiler(C,
                                     (FieldOffset - Pos),
                                     ElementBuilderName,
                                     RenderScriptVar);

        // eb.add(...)
        C.addFieldIndexMapping(F);
        if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
          genAddElementToElementBuilder(C,
                                        F->getType(),
                                        FieldName,
                                        ElementBuilderName,
                                        RenderScriptVar,
                                        0);
        } else {
          std::string NewElementBuilderName(ElementBuilderName);
          NewElementBuilderName.append(1, '_');

          genBuildElement(C,
                          NewElementBuilderName.c_str(),
                          static_cast<const RSExportRecordType*>(F->getType()),
                          RenderScriptVar,
                          /* IsInline = */true);

          const std::string &VarName = FieldName;  // Hack for EB_ADD macro
          EB_ADD(NewElementBuilderName << ".create()");
        }

        if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
          // There is padding within the field type. This is only necessary
          // for HC-targeted APIs.
          genAddPaddingToElementBuiler(C,
                                       (FieldAllocSize - FieldStoreSize),
                                       ElementBuilderName,
                                       RenderScriptVar);
        }

        Pos = FieldOffset + FieldAllocSize;
      }

      // There maybe some padding after the struct
      size_t RecordAllocSize = RSExportType::GetTypeAllocSize(ERT);

      genAddPaddingToElementBuiler(C,
                                   RecordAllocSize - Pos,
                                   ElementBuilderName,
                                   RenderScriptVar);
    } else {
      slangAssert(false && "Unknown class of type");
    }
  }
}

void RSReflection::genAddPaddingToElementBuiler(Context &C,
                                                int PaddingSize,
                                                const char *ElementBuilderName,
                                                const char *RenderScriptVar) {
  unsigned ArraySize = 0;   // Hack the EB_ADD macro
  while (PaddingSize > 0) {
    const std::string &VarName = C.createPaddingField();
    if (PaddingSize >= 4) {
      EB_ADD("Element.U32(" << RenderScriptVar << ")");
      PaddingSize -= 4;
    } else if (PaddingSize >= 2) {
      EB_ADD("Element.U16(" << RenderScriptVar << ")");
      PaddingSize -= 2;
    } else if (PaddingSize >= 1) {
      EB_ADD("Element.U8(" << RenderScriptVar << ")");
      PaddingSize -= 1;
    }
  }
  return;
}

#undef EB_ADD
/******** Methods to create Element in Java of given record type /end ********/

bool RSReflection::reflect(const std::string &OutputPathBase,
                           const std::string &OutputPackageName,
                           const std::string &RSPackageName,
                           const std::string &InputFileName,
                           const std::string &OutputBCFileName) {
  Context *C = NULL;
  std::string ResourceId = "";
  std::string PaddingPrefix = "";

  if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
    PaddingPrefix = "#padding_";
  } else {
    PaddingPrefix = "#rs_padding_";
  }

  if (!GetClassNameFromFileName(OutputBCFileName, ResourceId))
    return false;

  if (ResourceId.empty())
    ResourceId = "<Resource ID>";

  if (OutputPackageName.empty() || OutputPackageName == "-")
    C = new Context(OutputPathBase, InputFileName, "<Package Name>",
                    RSPackageName, ResourceId, PaddingPrefix, true);
  else
    C = new Context(OutputPathBase, InputFileName, OutputPackageName,
                    RSPackageName, ResourceId, PaddingPrefix, false);

  if (C != NULL) {
    std::string ErrorMsg, ScriptClassName;
    // class ScriptC_<ScriptName>
    if (!GetClassNameFromFileName(InputFileName, ScriptClassName))
      return false;

    if (ScriptClassName.empty())
      ScriptClassName = "<Input Script Name>";

    ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);

    if (mRSContext->getLicenseNote() != NULL) {
      C->setLicenseNote(*(mRSContext->getLicenseNote()));
    }

    if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
      std::cerr << "Failed to generate class " << ScriptClassName << " ("
                << ErrorMsg << ")" << std::endl;
      return false;
    }

    mGeneratedFileNames->push_back(ScriptClassName);

    // class ScriptField_<TypeName>
    for (RSContext::const_export_type_iterator TI =
             mRSContext->export_types_begin(),
             TE = mRSContext->export_types_end();
         TI != TE;
         TI++) {
      const RSExportType *ET = TI->getValue();

      if (ET->getClass() == RSExportType::ExportClassRecord) {
        const RSExportRecordType *ERT =
            static_cast<const RSExportRecordType*>(ET);

        if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
          std::cerr << "Failed to generate type class for struct '"
                    << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl;
          return false;
        }
      }
    }
  }

  return true;
}

/************************** RSReflection::Context **************************/
const char *const RSReflection::Context::ApacheLicenseNote =
    "/*\n"
    " * Copyright (C) 2011-2012 The Android Open Source Project\n"
    " *\n"
    " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
    " * you may not use this file except in compliance with the License.\n"
    " * You may obtain a copy of the License at\n"
    " *\n"
    " *      http://www.apache.org/licenses/LICENSE-2.0\n"
    " *\n"
    " * Unless required by applicable law or agreed to in writing, software\n"
    " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
    " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
    "implied.\n"
    " * See the License for the specific language governing permissions and\n"
    " * limitations under the License.\n"
    " */\n"
    "\n";

bool RSReflection::Context::openClassFile(const std::string &ClassName,
                                          std::string &ErrorMsg) {
  if (!mUseStdout) {
    mOF.clear();
    std::string Path =
        RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(),
                                                 mPackageName.c_str());

    if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg))
      return false;

    std::string ClassFile = Path + OS_PATH_SEPARATOR_STR + ClassName + ".java";

    mOF.open(ClassFile.c_str());
    if (!mOF.good()) {
      ErrorMsg = "failed to open file '" + ClassFile + "' for write";
      return false;
    }
  }
  return true;
}

const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) {
  switch (AM) {
    case AM_Public: return "public"; break;
    case AM_Protected: return "protected"; break;
    case AM_Private: return "private"; break;
    case AM_PublicSynchronized: return "public synchronized"; break;
    default: return ""; break;
  }
}

bool RSReflection::Context::startClass(AccessModifier AM,
                                       bool IsStatic,
                                       const std::string &ClassName,
                                       const char *SuperClassName,
                                       std::string &ErrorMsg) {
  if (mVerbose)
    std::cout << "Generating " << ClassName << ".java ..." << std::endl;

  // Open file for class
  if (!openClassFile(ClassName, ErrorMsg))
    return false;

  // License
  out() << mLicenseNote;

  // Notice of generated file
  out() << "/*" << std::endl;
  out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl;
  out() << " * The source Renderscript file: " << mInputRSFile << std::endl;
  out() << " */" << std::endl;

  // Package
  if (!mPackageName.empty())
    out() << "package " << mPackageName << ";" << std::endl;
  out() << std::endl;

  // Imports
  out() << "import " << mRSPackageName << ".*;" << std::endl;
  out() << "import android.content.res.Resources;" << std::endl;
  out() << std::endl;

  // All reflected classes should be annotated as hidden, so that they won't
  // be exposed in SDK.
  out() << "/**" << std::endl;
  out() << " * @hide" << std::endl;
  out() << " */" << std::endl;

  out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
        << ClassName;
  if (SuperClassName != NULL)
    out() << " extends " << SuperClassName;

  startBlock();

  mClassName = ClassName;

  return true;
}

void RSReflection::Context::endClass() {
  endBlock();
  if (!mUseStdout)
    mOF.close();
  clear();
  return;
}

void RSReflection::Context::startBlock(bool ShouldIndent) {
  if (ShouldIndent)
    indent() << "{" << std::endl;
  else
    out() << " {" << std::endl;
  incIndentLevel();
  return;
}

void RSReflection::Context::endBlock() {
  decIndentLevel();
  indent() << "}" << std::endl << std::endl;
  return;
}

void RSReflection::Context::startTypeClass(const std::string &ClassName) {
  indent() << "public static class " << ClassName;
  startBlock();
  return;
}

void RSReflection::Context::endTypeClass() {
  endBlock();
  return;
}

void RSReflection::Context::startFunction(AccessModifier AM,
                                          bool IsStatic,
                                          const char *ReturnType,
                                          const std::string &FunctionName,
                                          int Argc, ...) {
  ArgTy Args;
  va_list vl;
  va_start(vl, Argc);

  for (int i = 0; i < Argc; i++) {
    const char *ArgType = va_arg(vl, const char*);
    const char *ArgName = va_arg(vl, const char*);

    Args.push_back(std::make_pair(ArgType, ArgName));
  }
  va_end(vl);

  startFunction(AM, IsStatic, ReturnType, FunctionName, Args);

  return;
}

void RSReflection::Context::startFunction(AccessModifier AM,
                                          bool IsStatic,
                                          const char *ReturnType,
                                          const std::string &FunctionName,
                                          const ArgTy &Args) {
  indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
           << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";

  bool FirstArg = true;
  for (ArgTy::const_iterator I = Args.begin(), E = Args.end();
       I != E;
       I++) {
    if (!FirstArg)
      out() << ", ";
    else
      FirstArg = false;

    out() << I->first << " " << I->second;
  }

  out() << ")";
  startBlock();

  return;
}

void RSReflection::Context::endFunction() {
  endBlock();
  return;
}

bool RSReflection::Context::addTypeNameForElement(
    const std::string &TypeName) {
  if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
    mTypesToCheck.insert(TypeName);
    return true;
  } else {
    return false;
  }
}

bool RSReflection::Context::addTypeNameForFieldPacker(
    const std::string &TypeName) {
  if (mFieldPackerTypes.find(TypeName) == mFieldPackerTypes.end()) {
    mFieldPackerTypes.insert(TypeName);
    return true;
  } else {
    return false;
  }
}

}  // namespace slang
