/*
 * 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(const std::string &name0,
                                           const 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);
  const 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: {
    const 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: {
    const 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);
  const 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);
  const 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";
    const 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
