/*
 * Copyright 2010-2014, 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_export_reduce.h"
#include "slang_rs_reflect_utils.h"
#include "slang_version.h"

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

#define RS_TYPE_CLASS_SUPER_CLASS_NAME ".Script.FieldBase"

#define RS_TYPE_ITEM_CLASS_NAME "Item"

#define RS_TYPE_ITEM_SIZEOF_LEGACY "Item.sizeof"
#define RS_TYPE_ITEM_SIZEOF_CURRENT "mElement.getBytesSize()"

#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_REDUCE_INDEX_PREFIX "mExportReduceIdx_"

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

#define SAVED_RS_REFERENCE "mRSLocal"

namespace slang {

class RSReflectionJavaElementBuilder {
public:
  RSReflectionJavaElementBuilder(const char *ElementBuilderName,
                                 const RSExportRecordType *ERT,
                                 const char *RenderScriptVar,
                                 GeneratedFile *Out, const RSContext *RSContext,
                                 RSReflectionJava *Reflection);
  void generate();

private:
  void genAddElement(const RSExportType *ET, const std::string &VarName,
                     unsigned ArraySize);
  void genAddStatementStart();
  void genAddStatementEnd(const std::string &VarName, unsigned ArraySize);
  void genAddPadding(int PaddingSize);
  // TODO Will remove later due to field name information is not necessary for
  // C-reflect-to-Java
  std::string createPaddingField() {
    return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
  }

  const char *mElementBuilderName;
  const RSExportRecordType *mERT;
  const char *mRenderScriptVar;
  GeneratedFile *mOut;
  std::string mPaddingPrefix;
  int mPaddingFieldIndex;
  const RSContext *mRSContext;
  RSReflectionJava *mReflection;
};

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 nullptr;
}

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[] = {
      "addI16",     // DataTypeFloat16
      "addF32",     // DataTypeFloat32
      "addF64",     // DataTypeFloat64
      "addI8",      // DataTypeSigned8
      "addI16",     // DataTypeSigned16
      "addI32",     // DataTypeSigned32
      "addI64",     // DataTypeSigned64
      "addU8",      // DataTypeUnsigned8
      "addU16",     // DataTypeUnsigned16
      "addU32",     // DataTypeUnsigned32
      "addU64",     // DataTypeUnsigned64
      "addBoolean", // DataTypeBoolean
      "addU16",     // DataTypeUnsigned565
      "addU16",     // DataTypeUnsigned5551
      "addU16",     // DataTypeUnsigned4444
      "addMatrix",  // DataTypeRSMatrix2x2
      "addMatrix",  // DataTypeRSMatrix3x3
      "addMatrix",  // DataTypeRSMatrix4x4
      "addObj",     // DataTypeRSElement
      "addObj",     // DataTypeRSType
      "addObj",     // DataTypeRSAllocation
      "addObj",     // DataTypeRSSampler
      "addObj",     // DataTypeRSScript
      "addObj",     // DataTypeRSMesh
      "addObj",     // DataTypeRSPath
      "addObj",     // DataTypeRSProgramFragment
      "addObj",     // DataTypeRSProgramVertex
      "addObj",     // DataTypeRSProgramRaster
      "addObj",     // DataTypeRSProgramStore
      "addObj",     // DataTypeRSFont
  };
  unsigned TypeId = EPT->getType();

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

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

namespace {

enum {
  TypeNameWithConstantArrayBrackets = 0x01,
  TypeNameWithRecordElementName     = 0x02,
  TypeNameC                         = 0x04, // else Java
  TypeNameDefault                   = TypeNameWithConstantArrayBrackets|TypeNameWithRecordElementName
};

std::string GetTypeName(const RSExportType *ET, unsigned Style = TypeNameDefault) {
  switch (ET->getClass()) {
  case RSExportType::ExportClassPrimitive: {
    const auto ReflectionType =
        RSExportPrimitiveType::getRSReflectionType(static_cast<const RSExportPrimitiveType *>(ET));
    return (Style & TypeNameC ? ReflectionType->s_name : ReflectionType->java_name);
  }
  case RSExportType::ExportClassPointer: {
    slangAssert(!(Style & TypeNameC) &&
                "No need to support C type names for pointer types yet");
    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);
    const auto ReflectionType = EVT->getRSReflectionType(EVT);
    std::stringstream VecName;
    VecName << (Style & TypeNameC ? ReflectionType->s_name : ReflectionType->rs_java_vector_prefix)
            << EVT->getNumElement();
    return VecName.str();
  }
  case RSExportType::ExportClassMatrix: {
    slangAssert(!(Style & TypeNameC) &&
                "No need to support C type names for matrix types yet");
    return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET));
  }
  case RSExportType::ExportClassConstantArray: {
    const RSExportConstantArrayType *CAT =
        static_cast<const RSExportConstantArrayType *>(ET);
    std::string ElementTypeName = GetTypeName(CAT->getElementType(), Style);
    if (Style & TypeNameWithConstantArrayBrackets) {
      slangAssert(!(Style & TypeNameC) &&
                  "No need to support C type names for array types with brackets yet");
      ElementTypeName.append("[]");
    }
    return ElementTypeName;
  }
  case RSExportType::ExportClassRecord: {
    slangAssert(!(Style & TypeNameC) &&
                "No need to support C type names for record types yet");
    if (Style & TypeNameWithRecordElementName)
      return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
    else
      return ET->getName();
  }
  default: { slangAssert(false && "Unknown class of type"); }
  }

  return "";
}

std::string GetReduceResultTypeName(const RSExportType *ET) {
  switch (ET->getClass()) {
    case RSExportType::ExportClassConstantArray: {
      const RSExportConstantArrayType *const CAT = static_cast<const RSExportConstantArrayType *>(ET);
      return "resultArray" + std::to_string(CAT->getNumElement()) + "_" +
          GetTypeName(CAT->getElementType(),
                      (TypeNameDefault & ~TypeNameWithRecordElementName) | TypeNameC);
    }
    case RSExportType::ExportClassRecord:
      return "resultStruct_" + GetTypeName(ET,
                                           (TypeNameDefault & ~TypeNameWithRecordElementName) | TypeNameC);
    default:
      return "result_" + GetTypeName(ET, TypeNameDefault | TypeNameC);
  }
}

std::string GetReduceResultTypeName(const RSExportReduce *ER) {
  return GetReduceResultTypeName(ER->getResultType());
}

} // end anonymous namespace

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() == 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() == 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 {
        slangAssert(false && "Vectors should be size 2, 3, 4");
      }
    } else if (EVT->getType() == 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 "";
}

// If FromIntegerType == DestIntegerType, then Value is returned.
// Otherwise, return a Java expression that zero-extends the value
// Value, assumed to be of type FromIntegerType, to the integer type
// DestIntegerType.
//
// Intended operations:
//  byte  -> {byte,int,short,long}
//  short -> {short,int,long}
//  int   -> {int,long}
//  long  -> long
static std::string ZeroExtendValue(const std::string &Value,
                                   const std::string &FromIntegerType,
                                   const std::string &DestIntegerType) {
#ifndef __DISABLE_ASSERTS
  // Integer types arranged in increasing order by width
  const std::vector<std::string> ValidTypes{"byte", "short", "int", "long"};
  auto FromTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), FromIntegerType);
  auto DestTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), DestIntegerType);
  // Check that both types are valid.
  slangAssert(FromTypeLoc != ValidTypes.end());
  slangAssert(DestTypeLoc != ValidTypes.end());
  // Check that DestIntegerType is at least as wide as FromIntegerType.
  slangAssert(FromTypeLoc - ValidTypes.begin() <= DestTypeLoc - ValidTypes.begin());
#endif

  if (FromIntegerType == DestIntegerType) {
    return Value;
  }

  std::string Mask, MaskLiteralType;
  if (FromIntegerType == "byte") {
    Mask = "0xff";
    MaskLiteralType = "int";
  } else if (FromIntegerType == "short") {
    Mask = "0xffff";
    MaskLiteralType = "int";
  } else if (FromIntegerType == "int") {
    Mask = "0xffffffffL";
    MaskLiteralType = "long";
  } else {
    // long -> long casts should have already been handled.
    slangAssert(false && "Unknown integer type");
  }

  // Cast the mask to the appropriate type.
  if (MaskLiteralType != DestIntegerType) {
    Mask = "(" + DestIntegerType + ") " + Mask;
  }
  return "((" + DestIntegerType + ") ((" + Value + ") & " + Mask + "))";
}

/********************** Methods to generate script class **********************/
RSReflectionJava::RSReflectionJava(const RSContext *Context,
                                   std::vector<std::string> *GeneratedFileNames,
                                   const std::string &OutputBaseDirectory,
                                   const std::string &RSSourceFileName,
                                   const std::string &BitCodeFileName,
                                   bool EmbedBitcodeInJava)
    : mRSContext(Context), mPackageName(Context->getReflectJavaPackageName()),
      mRSPackageName(Context->getRSPackageName()),
      mOutputBaseDirectory(OutputBaseDirectory),
      mRSSourceFileName(RSSourceFileName), mBitCodeFileName(BitCodeFileName),
      mResourceId(RSSlangReflectUtils::JavaClassNameFromRSFileName(
          mBitCodeFileName.c_str())),
      mScriptClassName(RS_SCRIPT_CLASS_NAME_PREFIX +
                       RSSlangReflectUtils::JavaClassNameFromRSFileName(
                           mRSSourceFileName.c_str())),
      mEmbedBitcodeInJava(EmbedBitcodeInJava), mNextExportVarSlot(0),
      mNextExportFuncSlot(0), mNextExportForEachSlot(0),
      mNextExportReduceSlot(0), mLastError(""),
      mGeneratedFileNames(GeneratedFileNames), mFieldIndex(0) {
  slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
  slangAssert(!mPackageName.empty() && mPackageName != "-");

  mOutputDirectory = RSSlangReflectUtils::ComputePackagedPath(
                         OutputBaseDirectory.c_str(), mPackageName.c_str()) +
                     OS_PATH_SEPARATOR_STR;

  // mElement.getBytesSize only exists on JB+
  if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
      mItemSizeof = RS_TYPE_ITEM_SIZEOF_CURRENT;
  } else {
      mItemSizeof = RS_TYPE_ITEM_SIZEOF_LEGACY;
  }
}

bool RSReflectionJava::genScriptClass(const std::string &ClassName,
                                      std::string &ErrorMsg) {
  if (!startClass(AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
                  ErrorMsg))
    return false;

  genScriptClassConstructor();

  // Reflect exported variables
  for (auto I = mRSContext->export_vars_begin(),
            E = mRSContext->export_vars_end();
       I != E; I++)
    genExportVariable(*I);

  // Reflect exported forEach functions (only available on ICS+)
  if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
    for (auto I = mRSContext->export_foreach_begin(),
              E = mRSContext->export_foreach_end();
         I != E; I++) {
      genExportForEach(*I);
    }
  }

  // Reflect exported new-style reduce functions
  for (const RSExportType *ResultType : mRSContext->getReduceResultTypes(
           // FilterIn
           exportableReduce,

           // Compare
           [](const RSExportType *A, const RSExportType *B)
           { return GetReduceResultTypeName(A) < GetReduceResultTypeName(B); }))
    genExportReduceResultType(ResultType);
  for (auto I = mRSContext->export_reduce_begin(),
            E = mRSContext->export_reduce_end();
       I != E; ++I)
    genExportReduce(*I);

  // Reflect exported functions (invokable)
  for (auto I = mRSContext->export_funcs_begin(),
            E = mRSContext->export_funcs_end();
       I != E; ++I)
    genExportFunction(*I);

  endClass();

  return true;
}

void RSReflectionJava::genScriptClassConstructor() {
  std::string className(RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
      mRSSourceFileName.c_str()));
  // Provide a simple way to reference this object.
  mOut.indent() << "private static final String " RS_RESOURCE_NAME " = \""
                << getResourceId() << "\";\n";

  // Generate a simple constructor with only a single parameter (the rest
  // can be inferred from information we already have).
  mOut.indent() << "// Constructor\n";
  startFunction(AM_Public, false, nullptr, getClassName(), 1, "RenderScript",
                "rs");

  const bool haveReduceExportables =
    mRSContext->export_reduce_begin() != mRSContext->export_reduce_end();

  if (getEmbedBitcodeInJava()) {
    // Call new single argument Java-only constructor
    mOut.indent() << "super(rs,\n";
    mOut.indent() << "      " << RS_RESOURCE_NAME ",\n";
    mOut.indent() << "      " << className << ".getBitCode32(),\n";
    mOut.indent() << "      " << className << ".getBitCode64());\n";
  } else {
    // Call alternate constructor with required parameters.
    // Look up the proper raw bitcode resource id via the context.
    mOut.indent() << "this(rs,\n";
    mOut.indent() << "     rs.getApplicationContext().getResources(),\n";
    mOut.indent() << "     rs.getApplicationContext().getResources()."
                     "getIdentifier(\n";
    mOut.indent() << "         " RS_RESOURCE_NAME ", \"raw\",\n";
    mOut.indent()
        << "         rs.getApplicationContext().getPackageName()));\n";
    endFunction();

    // Alternate constructor (legacy) with 3 original parameters.
    startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
                  "rs", "Resources", "resources", "int", "id");
    // Call constructor of super class
    mOut.indent() << "super(rs, resources, id);\n";
  }

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

  for (auto I = mRSContext->export_vars_begin(),
            E = mRSContext->export_vars_end();
       I != E; I++) {
    const RSExportVar *EV = *I;
    if (!EV->getInit().isUninit()) {
      genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
    } else if (EV->getArraySize()) {
      // Always create an initial zero-init array object.
      mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
                    << GetTypeName(EV->getType(), TypeNameDefault & ~TypeNameWithConstantArrayBrackets) << "["
                    << EV->getArraySize() << "];\n";
      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(ET, Name.str(), EV->getInitArray(i));
      }
    }
    if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
      genTypeInstance(EV->getType());
    }
    genFieldPackerInstance(EV->getType());
  }

  if (haveReduceExportables) {
    mOut.indent() << SAVED_RS_REFERENCE << " = rs;\n";
  }

  // Reflect argument / return types in kernels

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

    const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
    for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
         BI != EI; BI++) {
      if (*BI != nullptr) {
        genTypeInstanceFromPointer(*BI);
      }
    }

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

  for (auto I = mRSContext->export_reduce_begin(),
            E = mRSContext->export_reduce_end();
       I != E; I++) {
    const RSExportReduce *ER = *I;

    const RSExportType *RT = ER->getResultType();
    slangAssert(RT != nullptr);
    if (!exportableReduce(RT))
      continue;

    genTypeInstance(RT);

    const RSExportReduce::InTypeVec &InTypes = ER->getAccumulatorInTypes();
    for (RSExportReduce::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
         BI != EI; BI++) {
      slangAssert(*BI != nullptr);
      genTypeInstance(*BI);
    }
  }

  endFunction();

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

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

  if (haveReduceExportables) {
    // We save a private copy of rs in order to create temporary
    // allocations in the reduce_* entry points.
    mOut.indent() << "private RenderScript " << SAVED_RS_REFERENCE << ";\n";
  }
}

void RSReflectionJava::genInitBoolExportVariable(const std::string &VarName,
                                                 const clang::APValue &Val) {
  slangAssert(!Val.isUninit() && "Not a valid initializer");
  slangAssert((Val.getKind() == clang::APValue::Int) &&
              "Bool type has wrong initial APValue");

  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";

  mOut << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";\n";
}

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

  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
  genInitValue(Val, false);
  mOut << ";\n";
}

void RSReflectionJava::genInitExportVariable(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() == DataTypeBoolean) {
      genInitBoolExportVariable(VarName, Val);
    } else {
      genInitPrimitiveExportVariable(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\n";
    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(Name, Val);
      }
      break;
    }
    case clang::APValue::Vector: {
      std::stringstream VecName;
      VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
              << EVT->getNumElement();
      mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
                    << VecName.str() << "();\n";

      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(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");

      mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName
                 << " = new " << ERT->getElementName()
                 <<  "." RS_TYPE_ITEM_CLASS_NAME"();\n";

      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(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"); }
  }
}

void RSReflectionJava::genExportVariable(const RSExportVar *EV) {
  const RSExportType *ET = EV->getType();

  mOut.indent() << "private final static int " << RS_EXPORT_VAR_INDEX_PREFIX
                << EV->getName() << " = " << getNextExportVarSlot() << ";\n";

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

void RSReflectionJava::genExportFunction(const RSExportFunc *EF) {
  mOut.indent() << "private final static int " << RS_EXPORT_FUNC_INDEX_PREFIX
                << EF->getName() << " = " << getNextExportFuncSlot() << ";\n";

  // invoke_*()
  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()));
    }
  }

  if (mRSContext->getTargetAPI() >= SLANG_M_TARGET_API) {
    startFunction(AM_Public, false, "Script.InvokeID",
                  "getInvokeID_" + EF->getName(), 0);

    mOut.indent() << "return createInvokeID(" << RS_EXPORT_FUNC_INDEX_PREFIX
                  << EF->getName() << ");\n";

    endFunction();
  }

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

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

    if (genCreateFieldPacker(ERT, FieldPackerName.c_str()))
      genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());

    mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
                  << ", " << FieldPackerName << ");\n";
  }

  endFunction();
}

void RSReflectionJava::genPairwiseDimCheck(std::string name0,
                                           std::string name1) {

  mOut.indent() << "// Verify dimensions\n";
  mOut.indent() << "t0 = " << name0 << ".getType();\n";
  mOut.indent() << "t1 = " << name1 << ".getType();\n";
  mOut.indent() << "if ((t0.getCount() != t1.getCount()) ||\n";
  mOut.indent() << "    (t0.getX() != t1.getX()) ||\n";
  mOut.indent() << "    (t0.getY() != t1.getY()) ||\n";
  mOut.indent() << "    (t0.getZ() != t1.getZ()) ||\n";
  mOut.indent() << "    (t0.hasFaces()   != t1.hasFaces()) ||\n";
  mOut.indent() << "    (t0.hasMipmaps() != t1.hasMipmaps())) {\n";
  mOut.indent() << "    throw new RSRuntimeException(\"Dimension mismatch "
                << "between parameters " << name0 << " and " << name1
                << "!\");\n";
  mOut.indent() << "}\n\n";
}

void RSReflectionJava::genNullArrayCheck(const std::string &ArrayName) {
  mOut.indent() << "// Verify that \"" << ArrayName << "\" is non-null.\n";
  mOut.indent() << "if (" << ArrayName << " == null) {\n";
  mOut.indent() << "    throw new RSIllegalArgumentException(\"Array \\\""
                << ArrayName << "\\\" is null!\");\n";
  mOut.indent() << "}\n";
}

void RSReflectionJava::genVectorLengthCompatibilityCheck(const std::string &ArrayName,
                                                         unsigned VecSize) {
  mOut.indent() << "// Verify that the array length is a multiple of the vector size.\n";
  mOut.indent() << "if (" << ArrayName << ".length % " << std::to_string(VecSize)
                << " != 0) {\n";
  mOut.indent() << "    throw new RSIllegalArgumentException(\"Array \\\"" << ArrayName
                << "\\\" is not a multiple of " << std::to_string(VecSize)
                << " in length!\");\n";
  mOut.indent() << "}\n";
}

void RSReflectionJava::genExportForEach(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.
    mOut.indent() << "//private final static int "
                  << RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName() << " = "
                  << getNextExportForEachSlot() << ";\n";
    return;
  }

  mOut.indent() << "private final static int " << RS_EXPORT_FOREACH_INDEX_PREFIX
                << EF->getName() << " = " << getNextExportForEachSlot()
                << ";\n";

  // forEach_*()
  ArgTy Args;
  bool HasAllocation = false; // at least one in/out allocation?

  const RSExportForEach::InVec     &Ins     = EF->getIns();
  const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
  const RSExportType               *OET     = EF->getOutType();

  if (Ins.size() == 1) {
    HasAllocation = true;
    Args.push_back(std::make_pair("Allocation", "ain"));

  } else if (Ins.size() > 1) {
    HasAllocation = true;
    for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
         BI++) {

      Args.push_back(std::make_pair("Allocation",
                                    "ain_" + (*BI)->getName().str()));
    }
  }

  if (EF->hasOut() || EF->hasReturn()) {
    HasAllocation = true;
    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()));
    }
  }

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

    // TODO: add element checking
    mOut.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
                  << EF->getName() << ", " << EF->getSignatureMetadata()
                  << ", null, null);\n";

    endFunction();
  }

  if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
    if (HasAllocation) {
      startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);

      mOut.indent() << "forEach_" << EF->getName();
      mOut << "(";

      if (Ins.size() == 1) {
        mOut << "ain, ";

      } else if (Ins.size() > 1) {
        for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
             BI++) {

          mOut << "ain_" << (*BI)->getName().str() << ", ";
        }
      }

      if (EF->hasOut() || EF->hasReturn()) {
        mOut << "aout, ";
      }

      if (EF->hasUsrData()) {
        mOut << Args.back().second << ", ";
      }

      // No clipped bounds to pass in.
      mOut << "null);\n";

      endFunction();
    }

    // Add the clipped kernel parameters to the Args list.
    Args.push_back(std::make_pair("Script.LaunchOptions", "sc"));
  }

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

  if (InTypes.size() == 1) {
    if (InTypes.front() != nullptr) {
      genTypeCheck(InTypes.front(), "ain");
    }

  } else if (InTypes.size() > 1) {
    size_t Index = 0;
    for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
         BI != EI; BI++, ++Index) {

      if (*BI != nullptr) {
        genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
      }
    }
  }

  if (OET) {
    genTypeCheck(OET, "aout");
  }

  if (Ins.size() == 1 && (EF->hasOut() || EF->hasReturn())) {
    mOut.indent() << "Type t0, t1;";
    genPairwiseDimCheck("ain", "aout");

  } else if (Ins.size() > 1) {
    mOut.indent() << "Type t0, t1;";

    std::string In0Name = "ain_" + Ins[0]->getName().str();

    for (size_t index = 1; index < Ins.size(); ++index) {
      genPairwiseDimCheck(In0Name, "ain_" + Ins[index]->getName().str());
    }

    if (EF->hasOut() || EF->hasReturn()) {
      genPairwiseDimCheck(In0Name, "aout");
    }
  }

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

  if (Ins.size() == 1) {
    mOut << ", ain";
  } else if (Ins.size() > 1) {
    mOut << ", new Allocation[]{ain_" << Ins[0]->getName().str();

    for (size_t index = 1; index < Ins.size(); ++index) {
      mOut << ", ain_" << Ins[index]->getName().str();
    }

    mOut << "}";

  } else {
    mOut << ", (Allocation) null";
  }

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

  if (EF->hasUsrData())
    mOut << ", " << FieldPackerName;
  else
    mOut << ", null";

  if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
    mOut << ", sc);\n";
  } else {
    mOut << ");\n";
  }

  endFunction();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////

// Reductions with certain legal result types can only be reflected for NDK, not for Java.
bool RSReflectionJava::exportableReduce(const RSExportType *ResultType) {
  const RSExportType *CheckType = ResultType;
  if (ResultType->getClass() == RSExportType::ExportClassConstantArray)
    CheckType = static_cast<const RSExportConstantArrayType *>(ResultType)->getElementType();
  if (CheckType->getClass() == RSExportType::ExportClassRecord) {
    // No Java reflection for struct until http://b/22236498 is resolved.
    return false;
  }

  return true;
}

namespace {
enum MappingComment { MappingCommentWithoutType, MappingCommentWithCType };

// OUTPUTS
//   InputParamName      = name to use for input parameter
//   InputMappingComment = text showing the mapping from InputParamName to the corresponding
//                           accumulator function parameter name (and possibly type)
// INPUTS
//   NamePrefix          = beginning of parameter name (e.g., "in")
//   MappingComment      = whether or not InputMappingComment should contain type
//   ER                  = description of the reduction
//   InIdx               = which input (numbered from zero)
void getReduceInputStrings(std::string &InputParamName, std::string &InputMappingComment,
                           const std::string &NamePrefix, MappingComment Mapping,
                           const RSExportReduce *ER, size_t InIdx) {
  InputParamName = NamePrefix + std::to_string(InIdx+1);
  std::string TypeString;
  if (Mapping == MappingCommentWithCType) {
    const RSExportType *InType = ER->getAccumulatorInTypes()[InIdx];
    if (InType->getClass() == RSExportType::ExportClassRecord) {
      // convertToRTD doesn't understand this type
      TypeString = "/* struct <> */ ";
    } else {
      RSReflectionTypeData InTypeData;
      ER->getAccumulatorInTypes()[InIdx]->convertToRTD(&InTypeData);
      slangAssert(InTypeData.type->s_name != nullptr);
      if (InTypeData.vecSize > 1) {
        TypeString = InTypeData.type->s_name + std::to_string(InTypeData.vecSize) + " ";
      } else {
        TypeString = InTypeData.type->s_name + std::string(" ");
      }
    }
  }
  InputMappingComment = InputParamName + " = \"" + TypeString + std::string(ER->getAccumulatorIns()[InIdx]->getName()) + "\"";
}

} // end anonymous namespace

void RSReflectionJava::genExportReduce(const RSExportReduce *ER) {
  if (!exportableReduce(ER->getResultType()))
    return;

  // Generate the reflected function index.
  mOut.indent() << "private final static int " << RS_EXPORT_REDUCE_INDEX_PREFIX
                << ER->getNameReduce() << " = " << getNextExportReduceSlot()
                << ";\n";

  /****** remember resultSvType generation **********************************************************/

  // Two variants of reduce_* entry points get generated.
  // Array variant:
  //   result_<resultSvType> reduce_<name>(<devecSiIn1Type>[] in1, ..., <devecSiInNType>[] inN)
  // Allocation variant:
  //   result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN)
  //   result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN, Script.LaunchOptions sc)

  genExportReduceArrayVariant(ER);
  genExportReduceAllocationVariant(ER);
}

void RSReflectionJava::genExportReduceArrayVariant(const RSExportReduce *ER) {
  // Analysis of result type.  Returns early if result type is not
  // suitable for array method reflection.
  const RSExportType *const ResultType = ER->getResultType();
  auto ResultTypeClass = ResultType->getClass();
  switch (ResultTypeClass) {
      case RSExportType::ExportClassConstantArray:
      case RSExportType::ExportClassMatrix:
      case RSExportType::ExportClassPrimitive:
      case RSExportType::ExportClassVector:
        // Ok
        break;

      case RSExportType::ExportClassPointer:
        slangAssert(!"Should not get here with pointer type");
        return;

      case RSExportType::ExportClassRecord:
        // TODO: convertToRTD() cannot handle this.  Why not?
        return;

      default:
        slangAssert(!"Unknown export class");
        return;
  }
  RSReflectionTypeData ResultTypeData;
  ResultType->convertToRTD(&ResultTypeData);
  if (!ResultTypeData.type->java_name || !ResultTypeData.type->java_array_element_name ||
      (ResultTypeData.vecSize > 1 && !ResultTypeData.type->rs_java_vector_prefix)) {
    slangAssert(false);
    return;
  }
  const std::string ResultTypeName = GetReduceResultTypeName(ER);

  // Analysis of inputs.  Returns early if some input type is not
  // suitable for array method reflection.
  llvm::SmallVector<RSReflectionTypeData, 1> InsTypeData;
  ArgTy Args;
  const auto &Ins = ER->getAccumulatorIns();
  const auto &InTypes = ER->getAccumulatorInTypes();
  slangAssert(Ins.size() == InTypes.size());
  InsTypeData.resize(Ins.size());
  llvm::SmallVector<std::string, 1> InComments;
  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
    const RSExportType *const InType = InTypes[InIdx];
    switch (InType->getClass()) {
      case RSExportType::ExportClassMatrix:
      case RSExportType::ExportClassPrimitive:
      case RSExportType::ExportClassVector:
        // Ok
        break;

      case RSExportType::ExportClassConstantArray:
        // No
        return;

      case RSExportType::ExportClassPointer:
        slangAssert(!"Should not get here with pointer type");
        return;

      case RSExportType::ExportClassRecord:
        // TODO: convertToRTD() cannot handle this.  Why not?
        return;

      default:
        slangAssert(!"Unknown export class");
        return;
    }

    RSReflectionTypeData &InTypeData = InsTypeData[InIdx];
    InType->convertToRTD(&InTypeData);
    if (!InTypeData.type->java_name || !InTypeData.type->java_array_element_name ||
        (InTypeData.vecSize > 1 && !InTypeData.type->rs_java_vector_prefix)) {
      return;
    }

    std::string InputParamName, InputComment;
    getReduceInputStrings(InputParamName, InputComment, "in", MappingCommentWithoutType, ER, InIdx);
    if (InTypeData.vecSize > 1)
      InputComment += (", flattened " + std::to_string(InTypeData.vecSize) + "-vectors");
    InComments.push_back(InputComment);

    const std::string InputTypeName = std::string(InTypeData.type->java_array_element_name) + "[]";
    Args.push_back(std::make_pair(InputTypeName, InputParamName));
  }

  const std::string MethodName = "reduce_" + ER->getNameReduce();

  // result_<resultSvType> reduce_<name>(<devecSiIn1Type>[] in1, ..., <devecSiInNType>[] inN)

  for (const std::string &InComment : InComments)
    mOut.indent() << "// " << InComment << "\n";
  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
  slangAssert(Ins.size() == InTypes.size());
  slangAssert(Ins.size() == InsTypeData.size());
  slangAssert(Ins.size() == Args.size());
  std::string In1Length;
  std::string InputAllocationOutgoingArgumentList;
  std::vector<std::string> InputAllocationNames;
  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
    const std::string &ArgName = Args[InIdx].second;
    genNullArrayCheck(ArgName);
    std::string InLength = ArgName + ".length";
    const uint32_t VecSize = InsTypeData[InIdx].vecSize;
    if (VecSize > 1) {
      InLength += " / " + std::to_string(VecSize);
      genVectorLengthCompatibilityCheck(ArgName, VecSize);
    }
    if (InIdx == 0) {
      In1Length = InLength;
    } else {
      mOut.indent() << "// Verify that input array lengths are the same.\n";
      mOut.indent() << "if (" << In1Length << " != " << InLength << ") {\n";
      mOut.indent() << "    throw new RSRuntimeException(\"Array length mismatch "
                    << "between parameters \\\"" << Args[0].second << "\\\" and \\\"" << ArgName
                    << "\\\"!\");\n";
      mOut.indent() << "}\n";
    }
    // Create a temporary input allocation
    const std::string TempName = "a" + ArgName;
    mOut.indent() << "Allocation " << TempName << " = Allocation.createSized("
                  << SAVED_RS_REFERENCE << ", "
                  << RS_ELEM_PREFIX << InTypes[InIdx]->getElementName() << ", "
                  << InLength << ");\n";
    mOut.indent() << TempName << ".setAutoPadding(true);\n";
    mOut.indent() << TempName << ".copyFrom(" << ArgName << ");\n";
    // ... and put that input allocation on the outgoing argument list
    if (!InputAllocationOutgoingArgumentList.empty())
      InputAllocationOutgoingArgumentList += ", ";
    InputAllocationOutgoingArgumentList += TempName;
    // ... and keep track of it for setting result.mTempIns
    InputAllocationNames.push_back(TempName);
  }

  mOut << "\n";
  mOut.indent() << ResultTypeName << " result = " << MethodName << "(" << InputAllocationOutgoingArgumentList << ", null);\n";
  if (!InputAllocationNames.empty()) {
    mOut.indent() << "result.mTempIns = new Allocation[]{";
    bool EmittedFirst = false;
    for (const std::string &InputAllocationName : InputAllocationNames) {
      if (!EmittedFirst) {
        EmittedFirst = true;
      } else {
        mOut << ", ";
      }
      mOut << InputAllocationName;
    }
    mOut << "};\n";
  }
  mOut.indent() << "return result;\n";
  endFunction();
}

void RSReflectionJava::genExportReduceAllocationVariant(const RSExportReduce *ER) {
  const auto &Ins = ER->getAccumulatorIns();
  const auto &InTypes = ER->getAccumulatorInTypes();
  const RSExportType *ResultType = ER->getResultType();

  llvm::SmallVector<std::string, 1> InComments;
  ArgTy Args;
  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
    std::string InputParamName, InputComment;
    getReduceInputStrings(InputParamName, InputComment, "ain", MappingCommentWithCType, ER, InIdx);
    InComments.push_back(InputComment);
    Args.push_back(std::make_pair("Allocation", InputParamName));
  }

  const std::string MethodName = "reduce_" + ER->getNameReduce();
  const std::string ResultTypeName = GetReduceResultTypeName(ER);

  // result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN)

  for (const std::string &InComment : InComments)
    mOut.indent() << "// " << InComment << "\n";
  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
  mOut.indent() << "return " << MethodName << "(";
  bool EmittedFirstArg = false;
  for (const auto &Arg : Args) {
    if (!EmittedFirstArg) {
      EmittedFirstArg = true;
    } else {
      mOut << ", ";
    }
    mOut << Arg.second;
  }
  mOut << ", null);\n";
  endFunction();

  // result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN, Script.LaunchOptions sc)

  static const char FormalOptionsName[] = "sc";
  Args.push_back(std::make_pair("Script.LaunchOptions", FormalOptionsName));
  for (const std::string &InComment : InComments)
    mOut.indent() << "// " << InComment << "\n";
  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
  const std::string &In0Name = Args[0].second;
  // Sanity-check inputs
  if (Ins.size() > 1)
    mOut.indent() << "Type t0, t1;\n";
  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
    const std::string &InName = Args[InIdx].second;
    genTypeCheck(InTypes[InIdx], InName.c_str());
    if (InIdx > 0)
      genPairwiseDimCheck(In0Name.c_str(), InName.c_str());
  }
  // Create a temporary output allocation
  const char OutputAllocName[] = "aout";
  const size_t OutputAllocLength =
      ResultType->getClass() == RSExportType::ExportClassConstantArray
      ? static_cast<const RSExportConstantArrayType *>(ResultType)->getNumElement()
      : 1;
  mOut.indent() << "Allocation " << OutputAllocName << " = Allocation.createSized("
                << SAVED_RS_REFERENCE << ", "
                << RS_ELEM_PREFIX << ResultType->getElementName() << ", "
                << OutputAllocLength << ");\n";
  mOut.indent() << OutputAllocName << ".setAutoPadding(true);\n";
  // Call the underlying reduce entry point
  mOut.indent() << "reduce(" << RS_EXPORT_REDUCE_INDEX_PREFIX << ER->getNameReduce()
                << ", new Allocation[]{" << In0Name;
  for (size_t InIdx = 1, InEnd = Ins.size(); InIdx < InEnd; ++InIdx)
    mOut << ", " << Args[InIdx].second;
  mOut << "}, " << OutputAllocName << ", " << FormalOptionsName << ");\n";
  mOut.indent() << "return new " << ResultTypeName << "(" << OutputAllocName << ");\n";
  endFunction();
}

namespace {

// When we've copied the Allocation to a Java array, how do we
// further process the elements of that array?
enum MapFromAllocation {
  MapFromAllocationTrivial,  // no further processing
  MapFromAllocationPositive, // need to ensure elements are positive (range check)
  MapFromAllocationBoolean,  // need to convert elements from byte to boolean
  MapFromAllocationPromote   // need to zero extend elements
};

// Return Java expression that maps from an Allocation element to a Java non-vector result.
//
// MFA                     = mapping kind
// ArrayElementTypeName    = type of InVal (having been copied out of Allocation to Java array)
// ReflectedScalarTypeName = type of mapped value
// InVal                   = input value that must be mapped
//
std::string genReduceResultMapping(MapFromAllocation MFA,
                                   const std::string &ArrayElementTypeName,
                                   const std::string &ReflectedScalarTypeName,
                                   const char *InVal) {
  switch (MFA) {
    default:
      slangAssert(!"Unknown MapFromAllocation");
      // and fall through
    case MapFromAllocationPositive: // range checking must be done separately
    case MapFromAllocationTrivial:
      return InVal;
    case MapFromAllocationBoolean:
      return std::string(InVal) + std::string(" != 0");
    case MapFromAllocationPromote:
      return ZeroExtendValue(InVal,
                             ArrayElementTypeName,
                             ReflectedScalarTypeName);
  }
}

// Return Java expression that maps from an Allocation element to a Java vector result.
//
// MFA                     = mapping kind
// ArrayElementTypeName    = type of InVal (having been copied out of Allocation to Java array)
// ReflectedScalarTypeName = type of mapped value
// VectorTypeName          = type of vector
// VectorElementCount      = number of elements in the vector
// InArray                 = input array containing vector elements
// InIdx                   = index of first vector element within InArray (or nullptr, if 0)
//
std::string genReduceResultVectorMapping(MapFromAllocation MFA,
                                         const std::string &ArrayElementTypeName,
                                         const std::string &ReflectedScalarTypeName,
                                         const std::string &VectorTypeName,
                                         unsigned VectorElementCount,
                                         const char *InArray, const char *InIdx = nullptr) {
  std::string result = "new " + VectorTypeName + "(";
  for (unsigned VectorElementIdx = 0; VectorElementIdx < VectorElementCount; ++VectorElementIdx) {
    if (VectorElementIdx)
     result += ", ";

    std::string ArrayElementName = std::string(InArray) + "[";
    if (InIdx)
      ArrayElementName += std::string(InIdx) + "+";
    ArrayElementName += std::to_string(VectorElementIdx) + "]";

    result += genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
                                     ArrayElementName.c_str());
  }
  result += ")";
  return result;
}

void genReduceResultRangeCheck(GeneratedFile &Out, const char *InVal) {
  Out.indent() << "if (" << InVal << " < 0)\n";
  Out.indent() << "    throw new RSRuntimeException(\"Result is not representible in Java\");\n";
}

} // end anonymous namespace

void RSReflectionJava::genExportReduceResultType(const RSExportType *ResultType) {
  if (!exportableReduce(ResultType))
    return;

  const std::string ClassName = GetReduceResultTypeName(ResultType);
  const std::string GetMethodReturnTypeName = GetTypeName(ResultType);
  mOut.indent() << "// To obtain the result, invoke get(), which blocks\n";
  mOut.indent() << "// until the asynchronously-launched operation has completed.\n";
  mOut.indent() << "public static class " << ClassName;
  mOut.startBlock();
  startFunction(AM_Public, false, GetMethodReturnTypeName.c_str(), "get", 0);

  RSReflectionTypeData TypeData;
  ResultType->convertToRTD(&TypeData);

  const std::string UnbracketedResultTypeName =
      GetTypeName(ResultType, TypeNameDefault & ~TypeNameWithConstantArrayBrackets);
  const std::string ReflectedScalarTypeName = TypeData.type->java_name;
  // Note: MATRIX* types do not have a java_array_element_name
  const std::string ArrayElementTypeName =
      TypeData.type->java_array_element_name
      ? std::string(TypeData.type->java_array_element_name)
      : ReflectedScalarTypeName;

  MapFromAllocation MFA = MapFromAllocationTrivial;
  if (std::string(TypeData.type->rs_type) == "UNSIGNED_64")
    MFA = MapFromAllocationPositive;
  else if (ReflectedScalarTypeName == "boolean")
    MFA = MapFromAllocationBoolean;
  else if (ReflectedScalarTypeName != ArrayElementTypeName)
    MFA = MapFromAllocationPromote;

  mOut.indent() << "if (!mGotResult)";
  mOut.startBlock();

  if (TypeData.vecSize == 1) { // result type is non-vector
    // <ArrayElementType>[] outArray = new <ArrayElementType>[1];
    // mOut.copyTo(outArray);
    mOut.indent() << ArrayElementTypeName << "[] outArray = new " << ArrayElementTypeName
                  << "[" << std::max(TypeData.arraySize, 1U) << "];\n";
    mOut.indent() << "mOut.copyTo(outArray);\n";
    if (TypeData.arraySize == 0) { // result type is non-array non-vector
      // mResult = outArray[0]; // but there are several special cases
      if (MFA == MapFromAllocationPositive)
        genReduceResultRangeCheck(mOut, "outArray[0]");
      mOut.indent() << "mResult = "
                    << genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
                                              "outArray[0]")
                    << ";\n";
    } else { // result type is array of non-vector
      if (MFA == MapFromAllocationTrivial) {
        // mResult = outArray;
        mOut.indent() << "mResult = outArray;\n";
      } else {
        // <ResultType> result = new <UnbracketedResultType>[<ArrayElementCount>];
        // for (unsigned Idx = 0; Idx < <ArrayElementCount>; ++Idx)
        //   result[Idx] = <Transform>(outArray[Idx]);
        // mResult = result; // but there are several special cases
        if (MFA != MapFromAllocationPositive) {
          mOut.indent() << GetTypeName(ResultType) << " result = new "
                        << UnbracketedResultTypeName
                        << "[" << TypeData.arraySize << "];\n";
        }
        mOut.indent() << "for (int Idx = 0; Idx < " << TypeData.arraySize << "; ++Idx)";
        mOut.startBlock();
        if (MFA == MapFromAllocationPositive) {
          genReduceResultRangeCheck(mOut, "outArray[Idx]");
        } else {
          mOut.indent() << "result[Idx] = "
                        << genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
                                                     "outArray[Idx]")
                        << ";\n";
        }
        mOut.endBlock();
        mOut.indent() << "mResult = " << (MFA == MapFromAllocationPositive ? "outArray" : "result") << ";\n";
      }
    }
  } else { // result type is vector or array of vector
    // <ArrayElementType>[] outArray = new <ArrayElementType>[<VectorElementCount> * <ArrayElementCount>];
    // mOut.copyTo(outArray);
    const unsigned VectorElementCount = TypeData.vecSize;
    const unsigned OutArrayElementCount = VectorElementCount * std::max(TypeData.arraySize, 1U);
    mOut.indent() << ArrayElementTypeName << "[] outArray = new " << ArrayElementTypeName
                  << "[" << OutArrayElementCount << "];\n";
    mOut.indent() << "mOut.copyTo(outArray);\n";
    if (MFA == MapFromAllocationPositive) {
      mOut.indent() << "for (int Idx = 0; Idx < " << OutArrayElementCount << "; ++Idx)";
      mOut.startBlock();
      genReduceResultRangeCheck(mOut, "outArray[Idx]");
      mOut.endBlock();
    }
    if (TypeData.arraySize == 0) { // result type is vector
      // mResult = new <ResultType>(outArray[0], outArray[1] ...); // but there are several special cases
      mOut.indent() << "mResult = "
                    << genReduceResultVectorMapping(MFA,
                                                    ArrayElementTypeName, ReflectedScalarTypeName,
                                                    GetTypeName(ResultType), VectorElementCount,
                                                    "outArray")
                    << ";\n";
    } else { // result type is array of vector
      // <ResultType> result = new <UnbracketedResultType>[<ArrayElementCount>];
      // for (unsigned Idx = 0; Idx < <ArrayElementCount>; ++Idx)
      //   result[Idx] = new <UnbracketedResultType>(outArray[<ArrayElementCount>*Idx+0],
      //                                             outArray[<ArrayElementCount>*Idx+1]...);
      // mResult = result; // but there are several special cases
      mOut.indent() << GetTypeName(ResultType) << " result = new "
                    << UnbracketedResultTypeName
                    << "[" << TypeData.arraySize << "];\n";
      mOut.indent() << "for (int Idx = 0; Idx < " << TypeData.arraySize << "; ++Idx)";
      mOut.startBlock();
      mOut.indent() << "result[Idx] = "
                    << genReduceResultVectorMapping(MFA,
                                                    ArrayElementTypeName, ReflectedScalarTypeName,
                                                    UnbracketedResultTypeName, VectorElementCount,
                                                    "outArray", (std::to_string(VectorElementCount) + "*Idx").c_str())
                    << ";\n";
      mOut.endBlock();
      mOut.indent() << "mResult = result;\n";
    }
  }

  mOut.indent() << "mOut.destroy();\n";
  mOut.indent() << "mOut = null;  // make Java object eligible for garbage collection\n";
  mOut.indent() << "if (mTempIns != null)";
  mOut.startBlock();
  mOut.indent() << "for (Allocation tempIn : mTempIns)";
  mOut.startBlock();
  mOut.indent() << "tempIn.destroy();\n";
  mOut.endBlock();
  mOut.indent() << "mTempIns = null;  // make Java objects eligible for garbage collection\n";
  mOut.endBlock();
  mOut.indent() << "mGotResult = true;\n";
  mOut.endBlock();

  mOut.indent() << "return mResult;\n";
  endFunction();

  startFunction(AM_Private, false, nullptr, ClassName, 1, "Allocation", "out");
  // TODO: Generate allocation type check and size check?  Or move
  // responsibility for instantiating the Allocation here, instead of
  // the reduce_* method?
  mOut.indent() << "mTempIns = null;\n";
  mOut.indent() << "mOut = out;\n";
  mOut.indent() << "mGotResult = false;\n";
  endFunction();
  mOut.indent() << "private Allocation[] mTempIns;\n";
  mOut.indent() << "private Allocation mOut;\n";
  // TODO: If result is reference type rather than primitive type, we
  // could omit mGotResult and use mResult==null to indicate that we
  // haven't obtained the result yet.
  mOut.indent() << "private boolean mGotResult;\n";
  mOut.indent() << "private " << GetMethodReturnTypeName << " mResult;\n";
  mOut.endBlock();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////

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

void RSReflectionJava::genTypeInstance(const RSExportType *ET) {
  switch (ET->getClass()) {
  case RSExportType::ExportClassPrimitive:
  case RSExportType::ExportClassVector:
  case RSExportType::ExportClassConstantArray: {
    std::string TypeName = ET->getElementName();
    if (addTypeNameForElement(TypeName)) {
      mOut.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
                    << "(rs);\n";
    }
    break;
  }

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

  default:
    break;
  }
}

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

  default:
    break;
  }
}

void RSReflectionJava::genTypeCheck(const RSExportType *ET,
                                    const char *VarName) {
  mOut.indent() << "// check " << VarName << "\n";

  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()) {
    mOut.indent() << "if (!" << VarName
                  << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
                  << TypeName << ")) {\n";
    mOut.indent() << "    throw new RSRuntimeException(\"Type mismatch with "
                  << TypeName << "!\");\n";
    mOut.indent() << "}\n";
  }
}

void RSReflectionJava::genPrimitiveTypeExportVariable(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(TypeName, EV->getName());

  if (EV->isConst()) {
    mOut.indent() << "public final static " << TypeName
                  << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
    const clang::APValue &Val = EV->getInit();
    genInitValue(Val, EPT->getType() == DataTypeBoolean);
    mOut << ";\n";
  } else {
    // set_*()
    // This must remain synchronized, since multiple Dalvik threads may
    // be calling setters.
    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
                  TypeName.c_str(), "v");
    if ((EPT->getElementSizeInBytes() < 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;
      mOut.indent() << "if (" << FPName << "!= null) {\n";
      mOut.increaseIndent();
      mOut.indent() << FPName << ".reset();\n";
      mOut.decreaseIndent();
      mOut.indent() << "} else {\n";
      mOut.increaseIndent();
      mOut.indent() << FPName << " = new FieldPacker(" << EPT->getElementSizeInBytes()
                    << ");\n";
      mOut.decreaseIndent();
      mOut.indent() << "}\n";

      genPackVarOfType(EPT, "v", FPName.c_str());
      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
                    << ", " << FPName << ");\n";
    } else {
      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
                    << ", v);\n";
    }

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

    endFunction();
  }

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

void RSReflectionJava::genInitValue(const clang::APValue &Val, bool asBool) {
  switch (Val.getKind()) {
  case clang::APValue::Int: {
    llvm::APInt api = Val.getInt();
    if (asBool) {
      mOut << ((api.getSExtValue() == 0) ? "false" : "true");
    } else {
      // TODO: Handle unsigned correctly
      mOut << api.getSExtValue();
      if (api.getBitWidth() > 32) {
        mOut << "L";
      }
    }
    break;
  }

  case clang::APValue::Float: {
    llvm::APFloat apf = Val.getFloat();
    llvm::SmallString<30> s;
    apf.toString(s);
    mOut << s.c_str();
    if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
      if (s.count('.') == 0) {
        mOut << ".f";
      } else {
        mOut << "f";
      }
    }
    break;
  }

  case clang::APValue::ComplexInt:
  case clang::APValue::ComplexFloat:
  case clang::APValue::LValue:
  case clang::APValue::Vector: {
    slangAssert(false && "Primitive type cannot have such kind of initializer");
    break;
  }

  default: { slangAssert(false && "Unknown kind of initializer"); }
  }
}

void RSReflectionJava::genPointerTypeExportVariable(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(TypeName, VarName);

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

  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
  mOut.indent() << "if (v == null) bindAllocation(null, "
                << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";

  if (PointeeType->getClass() == RSExportType::ExportClassRecord) {
    mOut.indent() << "else bindAllocation(v.getAllocation(), "
                  << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
  } else {
    mOut.indent() << "else bindAllocation(v, " << RS_EXPORT_VAR_INDEX_PREFIX
                  << VarName << ");\n";
  }

  endFunction();

  genGetExportVariable(TypeName, VarName);
}

void RSReflectionJava::genVectorTypeExportVariable(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(TypeName, VarName);
  genSetExportVariable(TypeName, EV, 1);
  genGetExportVariable(TypeName, VarName);
  genGetFieldID(VarName);
}

void RSReflectionJava::genMatrixTypeExportVariable(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(TypeName, VarName);

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

    if (genCreateFieldPacker(ET, FieldPackerName))
      genPackVarOfType(ET, "v", FieldPackerName);
    mOut.indent() << "setVar(" RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
                  << FieldPackerName << ");\n";

    endFunction();
  }

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

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

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

  genPrivateExportVariable(TypeName, VarName);
  genSetExportVariable(TypeName, EV, static_cast<const RSExportConstantArrayType *>(ET)->getNumElement());
  genGetExportVariable(TypeName, VarName);
  genGetFieldID(VarName);
}

void RSReflectionJava::genRecordTypeExportVariable(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(TypeName, VarName);
  genSetExportVariable(TypeName, EV, 1);
  genGetExportVariable(TypeName, VarName);
  genGetFieldID(VarName);
}

void RSReflectionJava::genPrivateExportVariable(const std::string &TypeName,
                                                const std::string &VarName) {
  mOut.indent() << "private " << TypeName << " " << RS_EXPORT_VAR_PREFIX
                << VarName << ";\n";
}

// Dimension = array element count; otherwise, 1.
void RSReflectionJava::genSetExportVariable(const std::string &TypeName,
                                            const RSExportVar *EV,
                                            unsigned Dimension) {
  if (!EV->isConst()) {
    const char *FieldPackerName = "fp";
    std::string VarName = EV->getName();
    const RSExportType *ET = EV->getType();
    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
                  TypeName.c_str(), "v");
    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";

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

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

    endFunction();
  }
}

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

  mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";

  endFunction();
}

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

    mOut.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
                  << VarName << ", null);\n";

    endFunction();
  }
}

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

bool RSReflectionJava::genCreateFieldPacker(const RSExportType *ET,
                                            const char *FieldPackerName) {
  size_t AllocSize = ET->getAllocSize();
  if (AllocSize > 0)
    mOut.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
                  << AllocSize << ");\n";
  else
    return false;
  return true;
}

void RSReflectionJava::genPackVarOfType(const RSExportType *ET,
                                        const char *VarName,
                                        const char *FieldPackerName) {
  switch (ET->getClass()) {
  case RSExportType::ExportClassPrimitive:
  case RSExportType::ExportClassVector: {
    mOut.indent() << FieldPackerName << "."
                  << GetPackerAPIName(
                         static_cast<const RSExportPrimitiveType *>(ET)) << "("
                  << VarName << ");\n";
    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) {
      mOut.indent() << FieldPackerName << ".addI32(" << VarName
                    << ".getPtr());\n";
    } else {
      mOut.indent() << FieldPackerName << ".addI32(" << VarName
                    << ".getAllocation().getPtr());\n";
    }
    break;
  }
  case RSExportType::ExportClassMatrix: {
    mOut.indent() << FieldPackerName << ".addMatrix(" << VarName << ");\n";
    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));

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

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

    mOut.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();
      const RSExportType *T = F->getType();
      size_t FieldStoreSize = T->getStoreSize();
      size_t FieldAllocSize = T->getAllocSize();

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

      if (FieldOffset > Pos) {
        mOut.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos)
                      << ");\n";
      }

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

      // There is padding in the field type
      if (FieldAllocSize > FieldStoreSize) {
        mOut.indent() << FieldPackerName << ".skip("
                      << (FieldAllocSize - FieldStoreSize) << ");\n";
      }

      Pos = FieldOffset + FieldAllocSize;
    }

    // There maybe some padding after the struct
    if (ERT->getAllocSize() > Pos) {
      mOut.indent() << FieldPackerName << ".skip(" << ERT->getAllocSize() - Pos
                    << ");\n";
    }
    break;
  }
  default: { slangAssert(false && "Unknown class of type"); }
  }
}

void RSReflectionJava::genAllocateVarOfType(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())
    //  mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
    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();
    mOut.indent() << VarName << " = null;\n";
    break;
  }
  case RSExportType::ExportClassConstantArray: {
    const RSExportConstantArrayType *ECAT =
        static_cast<const RSExportConstantArrayType *>(T);
    const RSExportType *ElementType = ECAT->getElementType();

    mOut.indent() << VarName << " = new " << GetTypeName(ElementType) << "["
                  << ECAT->getNumElement() << "];\n";

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

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

      mOut.endBlock();
    }
    break;
  }
  case RSExportType::ExportClassVector:
  case RSExportType::ExportClassMatrix:
  case RSExportType::ExportClassRecord: {
    mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
    break;
  }
  }
}

void RSReflectionJava::genNewItemBufferIfNull(const char *Index) {
  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
  mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
       << "[getType().getX() /* count */];\n";
  if (Index != nullptr) {
    mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
                  << "] == null) ";
    mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
         << RS_TYPE_ITEM_CLASS_NAME << "();\n";
  }
}

void RSReflectionJava::genNewItemBufferPackerIfNull() {
  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " == null) ";
  mOut << RS_TYPE_ITEM_BUFFER_PACKER_NAME " = new FieldPacker("
       <<  mItemSizeof << " * getType().getX()/* count */);\n";
}

/********************** Methods to generate type class  **********************/
bool RSReflectionJava::genTypeClass(const RSExportRecordType *ERT,
                                    std::string &ErrorMsg) {
  std::string ClassName = ERT->getElementName();
  std::string superClassName = getRSPackageName();
  superClassName += RS_TYPE_CLASS_SUPER_CLASS_NAME;

  if (!startClass(AM_Public, false, ClassName, superClassName.c_str(),
                  ErrorMsg))
    return false;

  mGeneratedFileNames->push_back(ClassName);

  genTypeItemClass(ERT);

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

  genTypeClassConstructor(ERT);
  genTypeClassCopyToArrayLocal(ERT);
  genTypeClassCopyToArray(ERT);
  genTypeClassItemSetter(ERT);
  genTypeClassItemGetter(ERT);
  genTypeClassComponentSetter(ERT);
  genTypeClassComponentGetter(ERT);
  genTypeClassCopyAll(ERT);
  if (!mRSContext->isCompatLib()) {
    // Skip the resize method if we are targeting a compatibility library.
    genTypeClassResize();
  }

  endClass();

  resetFieldIndex();
  clearFieldIndexMap();

  return true;
}

void RSReflectionJava::genTypeItemClass(const RSExportRecordType *ERT) {
  mOut.indent() << "static public class " RS_TYPE_ITEM_CLASS_NAME;
  mOut.startBlock();

  // Sizeof should not be exposed for 64-bit; it is not accurate
  if (mRSContext->getTargetAPI() < 21) {
      mOut.indent() << "public static final int sizeof = " << ERT->getAllocSize()
                    << ";\n";
  }

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

  // Constructor
  mOut << "\n";
  mOut.indent() << RS_TYPE_ITEM_CLASS_NAME << "()";
  mOut.startBlock();

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

  // end Constructor
  mOut.endBlock();

  // end Item class
  mOut.endBlock();
}

void RSReflectionJava::genTypeClassConstructor(const RSExportRecordType *ERT) {
  const char *RenderScriptVar = "rs";

  startFunction(AM_Public, true, "Element", "createElement", 1, "RenderScript",
                RenderScriptVar);

  // TODO(all): Fix weak-refs + multi-context issue.
  // mOut.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
  //            << ".get();\n";
  // mOut.indent() << "if (e != null) return e;\n";
  RSReflectionJavaElementBuilder builder("eb", ERT, RenderScriptVar, &mOut,
                                         mRSContext, this);
  builder.generate();

  mOut.indent() << "return eb.create();\n";
  // mOut.indent() << "e = eb.create();\n";
  // mOut.indent() << RS_TYPE_ELEMENT_REF_NAME
  //            << " = new java.lang.ref.WeakReference<Element>(e);\n";
  // mOut.indent() << "return e;\n";
  endFunction();

  // private with element
  startFunction(AM_Private, false, nullptr, getClassName(), 1, "RenderScript",
                RenderScriptVar);
  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
  endFunction();

  // 1D without usage
  startFunction(AM_Public, false, nullptr, getClassName(), 2, "RenderScript",
                RenderScriptVar, "int", "count");

  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
  // Call init() in super class
  mOut.indent() << "init(" << RenderScriptVar << ", count);\n";
  endFunction();

  // 1D with usage
  startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
                RenderScriptVar, "int", "count", "int", "usages");

  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
  // Call init() in super class
  mOut.indent() << "init(" << RenderScriptVar << ", count, usages);\n";
  endFunction();

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

  // create1D without usage
  startFunction(AM_Public, true, getClassName().c_str(), "create1D", 2,
                "RenderScript", RenderScriptVar, "int", "dimX");
  mOut.indent() << "return create1D(" << RenderScriptVar
                << ", dimX, Allocation.USAGE_SCRIPT);\n";
  endFunction();

  // create2D without usage
  startFunction(AM_Public, true, getClassName().c_str(), "create2D", 3,
                "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY");
  mOut.indent() << "return create2D(" << RenderScriptVar
                << ", dimX, dimY, Allocation.USAGE_SCRIPT);\n";
  endFunction();

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

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

  // createTypeBuilder
  startFunction(AM_Public, true, "Type.Builder", "createTypeBuilder", 1,
                "RenderScript", RenderScriptVar);
  mOut.indent() << "Element e = createElement(" << RenderScriptVar << ");\n";
  mOut.indent() << "return new Type.Builder(rs, e);\n";
  endFunction();

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

void RSReflectionJava::genTypeClassCopyToArray(const RSExportRecordType *ERT) {
  startFunction(AM_Private, false, "void", "copyToArray", 2,
                RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index");

  genNewItemBufferPackerIfNull();
  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
                << mItemSizeof << ");\n";

  mOut.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
                   ");\n";

  endFunction();
}

void
RSReflectionJava::genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT) {
  startFunction(AM_Private, false, "void", "copyToArrayLocal", 2,
                RS_TYPE_ITEM_CLASS_NAME, "i", "FieldPacker", "fp");

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

  endFunction();
}

void RSReflectionJava::genTypeClassItemSetter(const RSExportRecordType *ERT) {
  startFunction(AM_PublicSynchronized, false, "void", "set", 3,
                RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
                "copyNow");
  genNewItemBufferIfNull(nullptr);
  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";

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

  mOut.indent() << "copyToArray(i, index);\n";
  mOut.indent() << "FieldPacker fp = new FieldPacker(" << mItemSizeof << ");\n";
  mOut.indent() << "copyToArrayLocal(i, fp);\n";
  mOut.indent() << "mAllocation.setFromFieldPacker(index, fp);\n";

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

  endFunction();
}

void RSReflectionJava::genTypeClassItemGetter(const RSExportRecordType *ERT) {
  startFunction(AM_PublicSynchronized, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1,
                "int", "index");
  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME
                << " == null) return null;\n";
  mOut.indent() << "return " << RS_TYPE_ITEM_BUFFER_NAME << "[index];\n";
  endFunction();
}

void
RSReflectionJava::genTypeClassComponentSetter(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 = F->getType()->getStoreSize();
    unsigned FieldIndex = getFieldIndex(F);

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

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

    if (FieldOffset > 0) {
      mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
                    << mItemSizeof << " + " << FieldOffset
                    << ");\n";
    } else {
      mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
                    << mItemSizeof << ");\n";
    }
    genPackVarOfType(F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);

    mOut.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize
                  << ");\n";
    genPackVarOfType(F->getType(), "v", "fp");
    mOut.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
                  << ", fp);\n";

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

    endFunction();
  }
}

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

void RSReflectionJava::genTypeClassCopyAll(const RSExportRecordType *ERT) {
  startFunction(AM_PublicSynchronized, false, "void", "copyAll", 0);

  mOut.indent() << "for (int ct = 0; ct < " << RS_TYPE_ITEM_BUFFER_NAME
                << ".length; ct++)"
                << " copyToArray(" << RS_TYPE_ITEM_BUFFER_NAME
                << "[ct], ct);\n";
  mOut.indent() << "mAllocation.setFromFieldPacker(0, "
                << RS_TYPE_ITEM_BUFFER_PACKER_NAME ");\n";

  endFunction();
}

void RSReflectionJava::genTypeClassResize() {
  startFunction(AM_PublicSynchronized, false, "void", "resize", 1, "int",
                "newSize");

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

  mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME
                   " != null) " RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
                   "new FieldPacker(" << mItemSizeof << " * getType().getX()/* count */);\n";

  endFunction();
}

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

/********** Methods to create Element in Java of given record type ***********/

RSReflectionJavaElementBuilder::RSReflectionJavaElementBuilder(
    const char *ElementBuilderName, const RSExportRecordType *ERT,
    const char *RenderScriptVar, GeneratedFile *Out, const RSContext *RSContext,
    RSReflectionJava *Reflection)
    : mElementBuilderName(ElementBuilderName), mERT(ERT),
      mRenderScriptVar(RenderScriptVar), mOut(Out), mPaddingFieldIndex(1),
      mRSContext(RSContext), mReflection(Reflection) {
  if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
    mPaddingPrefix = "#padding_";
  } else {
    mPaddingPrefix = "#rs_padding_";
  }
}

void RSReflectionJavaElementBuilder::generate() {
  mOut->indent() << "Element.Builder " << mElementBuilderName
                 << " = new Element.Builder(" << mRenderScriptVar << ");\n";
  genAddElement(mERT, "", /* ArraySize = */ 0);
}

void RSReflectionJavaElementBuilder::genAddElement(const RSExportType *ET,
                                                   const std::string &VarName,
                                                   unsigned ArraySize) {
  std::string ElementConstruct = GetBuiltinElementConstruct(ET);

  if (ElementConstruct != "") {
    genAddStatementStart();
    *mOut << ElementConstruct << "(" << mRenderScriptVar << ")";
    genAddStatementEnd(VarName, ArraySize);
  } else {

    switch (ET->getClass()) {
    case RSExportType::ExportClassPrimitive: {
      const RSExportPrimitiveType *EPT =
          static_cast<const RSExportPrimitiveType *>(ET);
      const char *DataTypeName =
          RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
      genAddStatementStart();
      *mOut << "Element.createUser(" << mRenderScriptVar
            << ", Element.DataType." << DataTypeName << ")";
      genAddStatementEnd(VarName, ArraySize);
      break;
    }
    case RSExportType::ExportClassVector: {
      const RSExportVectorType *EVT =
          static_cast<const RSExportVectorType *>(ET);
      const char *DataTypeName =
          RSExportPrimitiveType::getRSReflectionType(EVT)->rs_type;
      genAddStatementStart();
      *mOut << "Element.createVector(" << mRenderScriptVar
            << ", Element.DataType." << DataTypeName << ", "
            << EVT->getNumElement() << ")";
      genAddStatementEnd(VarName, ArraySize);
      break;
    }
    case RSExportType::ExportClassPointer:
      // Pointer type variable should be resolved in
      // GetBuiltinElementConstruct()
      slangAssert(false && "??");
      break;
    case RSExportType::ExportClassMatrix:
      // Matrix type variable should be resolved
      // in GetBuiltinElementConstruct()
      slangAssert(false && "??");
      break;
    case RSExportType::ExportClassConstantArray: {
      const RSExportConstantArrayType *ECAT =
          static_cast<const RSExportConstantArrayType *>(ET);

      const RSExportType *ElementType = ECAT->getElementType();
      if (ElementType->getClass() != RSExportType::ExportClassRecord) {
        genAddElement(ECAT->getElementType(), VarName, ECAT->getNumElement());
      } else {
        std::string NewElementBuilderName(mElementBuilderName);
        NewElementBuilderName.append(1, '_');

        RSReflectionJavaElementBuilder builder(
            NewElementBuilderName.c_str(),
            static_cast<const RSExportRecordType *>(ElementType),
            mRenderScriptVar, mOut, mRSContext, mReflection);
        builder.generate();

        ArraySize = ECAT->getNumElement();
        genAddStatementStart();
        *mOut << NewElementBuilderName << ".create()";
        genAddStatementEnd(VarName, ArraySize);
      }
      break;
    }
    case 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;
        int FieldOffset = F->getOffsetInParent();
        const RSExportType *T = F->getType();
        int FieldStoreSize = T->getStoreSize();
        int FieldAllocSize = T->getAllocSize();

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

        // Alignment
        genAddPadding(FieldOffset - Pos);

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

          RSReflectionJavaElementBuilder builder(
              NewElementBuilderName.c_str(),
              static_cast<const RSExportRecordType *>(F->getType()),
              mRenderScriptVar, mOut, mRSContext, mReflection);
          builder.generate();

          genAddStatementStart();
          *mOut << NewElementBuilderName << ".create()";
          genAddStatementEnd(FieldName, ArraySize);
        }

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

        Pos = FieldOffset + FieldAllocSize;
      }

      // There maybe some padding after the struct
      size_t RecordAllocSize = ERT->getAllocSize();

      genAddPadding(RecordAllocSize - Pos);
      break;
    }
    default:
      slangAssert(false && "Unknown class of type");
      break;
    }
  }
}

void RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize) {
  while (PaddingSize > 0) {
    const std::string &VarName = createPaddingField();
    genAddStatementStart();
    if (PaddingSize >= 4) {
      *mOut << "Element.U32(" << mRenderScriptVar << ")";
      PaddingSize -= 4;
    } else if (PaddingSize >= 2) {
      *mOut << "Element.U16(" << mRenderScriptVar << ")";
      PaddingSize -= 2;
    } else if (PaddingSize >= 1) {
      *mOut << "Element.U8(" << mRenderScriptVar << ")";
      PaddingSize -= 1;
    }
    genAddStatementEnd(VarName, 0);
  }
}

void RSReflectionJavaElementBuilder::genAddStatementStart() {
  mOut->indent() << mElementBuilderName << ".add(";
}

void
RSReflectionJavaElementBuilder::genAddStatementEnd(const std::string &VarName,
                                                   unsigned ArraySize) {
  *mOut << ", \"" << VarName << "\"";
  if (ArraySize > 0) {
    *mOut << ", " << ArraySize;
  }
  *mOut << ");\n";
  // TODO Review incFieldIndex.  It's probably better to assign the numbers at
  // the start rather
  // than as we're generating the code.
  mReflection->incFieldIndex();
}

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

bool RSReflectionJava::reflect() {
  std::string ErrorMsg;
  if (!genScriptClass(mScriptClassName, ErrorMsg)) {
    std::cerr << "Failed to generate class " << mScriptClassName << " ("
              << ErrorMsg << ")\n";
    return false;
  }

  mGeneratedFileNames->push_back(mScriptClassName);

  // 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(ERT, ErrorMsg)) {
        std::cerr << "Failed to generate type class for struct '"
                  << ERT->getName() << "' (" << ErrorMsg << ")\n";
        return false;
      }
    }
  }

  return true;
}

const char *RSReflectionJava::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 RSReflectionJava::startClass(AccessModifier AM, bool IsStatic,
                                  const std::string &ClassName,
                                  const char *SuperClassName,
                                  std::string &ErrorMsg) {
  // Open file for class
  std::string FileName = ClassName + ".java";
  if (!mOut.startFile(mOutputDirectory, FileName, mRSSourceFileName,
                      mRSContext->getLicenseNote(), true,
                      mRSContext->getVerbose())) {
    return false;
  }

  // Package
  if (!mPackageName.empty()) {
    mOut << "package " << mPackageName << ";\n";
  }
  mOut << "\n";

  // Imports
  mOut << "import " << mRSPackageName << ".*;\n";
  if (getEmbedBitcodeInJava()) {
    mOut << "import " << mPackageName << "."
          << RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
                 mRSSourceFileName.c_str()) << ";\n";
  } else {
    mOut << "import android.content.res.Resources;\n";
  }
  mOut << "\n";

  // All reflected classes should be annotated as hidden, so that they won't
  // be exposed in SDK.
  mOut << "/**\n";
  mOut << " * @hide\n";
  mOut << " */\n";

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

  mOut.startBlock();

  mClassName = ClassName;

  return true;
}

void RSReflectionJava::endClass() {
  mOut.endBlock();
  mOut.closeFile();
  clear();
}

void RSReflectionJava::startTypeClass(const std::string &ClassName) {
  mOut.indent() << "public static class " << ClassName;
  mOut.startBlock();
}

void RSReflectionJava::endTypeClass() { mOut.endBlock(); }

void RSReflectionJava::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);
}

void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
                                     const char *ReturnType,
                                     const std::string &FunctionName,
                                     const ArgTy &Args) {
  mOut.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)
      mOut << ", ";
    else
      FirstArg = false;

    mOut << I->first << " " << I->second;
  }

  mOut << ")";
  mOut.startBlock();
}

void RSReflectionJava::endFunction() { mOut.endBlock(); }

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

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

} // namespace slang
