Simplify field getters by removing unnecessary null checks. Add reflection for component-level getter and setter.

Change-Id: Ic6ea9f9e02400cbb7f43b6421d7adde6523b458c
diff --git a/slang_rs_reflection.hpp b/slang_rs_reflection.hpp
index c007f04..dc92dcd 100644
--- a/slang_rs_reflection.hpp
+++ b/slang_rs_reflection.hpp
@@ -17,7 +17,6 @@
 class RSContext;
 class RSExportVar;
 class RSExportFunc;
-class RSExportRecordType;
 
 class RSReflection {
 private:
@@ -49,6 +48,15 @@
         int mNextExportVarSlot;
         int mNextExportFuncSlot;
 
+        /*
+         * A mapping from a field in a record type to its index in the rsType instance.
+         * Only used when generates TypeClass (ScriptField_*).
+         */
+        typedef std::map<const RSExportRecordType::Field*, unsigned> FieldIndexMapTy;
+        FieldIndexMapTy mFieldIndexMap;
+        /* Field index of current processing TypeClass. */
+        unsigned mFieldIndex;
+
         inline void clear() {
             mClassName = "";
             mIndent = "";
@@ -138,6 +146,29 @@
 
         void startTypeClass(const std::string& ClassName);
         void endTypeClass();
+
+        inline void incFieldIndex() {
+            mFieldIndex++;
+        }
+
+        inline void resetFieldIndex() {
+            mFieldIndex = 0;
+        }
+
+        inline void addFieldIndexMapping(const RSExportRecordType::Field* F) {
+            assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && "Nested structure never occurs in C language.");
+            mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
+        }
+
+        inline unsigned getFieldIndex(const RSExportRecordType::Field* F) const {
+            FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
+            assert((I != mFieldIndexMap.end()) && "Requesting field is out of scope.");
+            return I->second;
+        }
+
+        inline void clearFieldIndexMap() {
+            mFieldIndexMap.clear();
+        }
     };
 
     bool openScriptFile(Context& C, const std::string& ClassName, std::string& ErrorMsg);
@@ -160,9 +191,11 @@
     bool genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
     void genTypeClassConstructor(Context& C, const RSExportRecordType* ERT);
     void genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT);
-    void genTypeClasSet(Context& C, const RSExportRecordType* ERT);
-    void genTypeClasGet(Context& C, const RSExportRecordType* ERT);
-    void genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT);
+    void genTypeClassItemSetter(Context& C, const RSExportRecordType* ERT);
+    void genTypeClassItemGetter(Context& C, const RSExportRecordType* ERT);
+    void genTypeClassComponentSetter(Context& C, const RSExportRecordType* ERT);
+    void genTypeClassComponentGetter(Context& C, const RSExportRecordType* ERT);
+    void genTypeClassCopyAll(Context& C, const RSExportRecordType* ERT);
 
     void genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar);
     void genAddElementToElementBuilder(Context& C, const RSExportType* ERT, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar);
@@ -170,6 +203,8 @@
 
     bool genCreateFieldPacker(Context& C, const RSExportType* T, const char* FieldPackerName);
     void genPackVarOfType(Context& C, const RSExportType* T, const char* VarName, const char* FieldPackerName);
+    void genNewItemBufferIfNull(Context& C, const char* Index);
+    void genNewItemBufferPackerIfNull(Context& C);
 
 public:
     RSReflection(const RSContext* Context) :