Split AnnotaionParam into String and Constant Expression params

This is needed to support constant expression lazy evaluation.

Test: build hidl-gen, hidl_test
Test: build hidl-gen on mac :)

Change-Id: I5f38b0d2cbea5928408379bff7f282a2cd63d03b
diff --git a/Annotation.cpp b/Annotation.cpp
index a3e49f8..7f3fc88 100644
--- a/Annotation.cpp
+++ b/Annotation.cpp
@@ -23,33 +23,12 @@
 
 namespace android {
 
+AnnotationParam::AnnotationParam(const std::string& name) : mName(name) {}
 
-AnnotationParam::AnnotationParam(const std::string &name,
-                std::vector<std::string> *values)
-: mName(name), mValues(values) {}
-
-AnnotationParam::AnnotationParam(const std::string &name,
-                std::vector<ConstantExpression *> *values)
-        : mName(name) {
-    mValues = new std::vector<std::string>();
-    for(ConstantExpression *ce : *values) {
-        mValues->push_back(ce->value() + " /* " + ce->description() + " */");
-    }
-}
-
-const std::string &AnnotationParam::getName() const {
+const std::string& AnnotationParam::getName() const {
     return mName;
 }
 
-const std::vector<std::string> *AnnotationParam::getValues() const {
-    return mValues;
-}
-
-const std::string &AnnotationParam::getSingleValue() const {
-    CHECK_EQ(mValues->size(), 1u) << mName << " requires one values but has multiple";
-    return mValues->at(0);
-}
-
 std::string AnnotationParam::getSingleString() const {
     std::string value = getSingleValue();
 
@@ -75,11 +54,44 @@
     return false;
 }
 
-Annotation::Annotation(const char *name,AnnotationParamVector *params)
-        : mName(name),
-          mParams(params) {
+StringAnnotationParam::StringAnnotationParam(const std::string& name,
+                                             std::vector<std::string>* values)
+    : AnnotationParam(name), mValues(values) {}
+
+std::vector<std::string> StringAnnotationParam::getValues() const {
+    return *mValues;
 }
 
+std::string StringAnnotationParam::getSingleValue() const {
+    CHECK_EQ(mValues->size(), 1u) << mName << " requires one value but has multiple";
+    return mValues->at(0);
+}
+
+ConstantExpressionAnnotationParam::ConstantExpressionAnnotationParam(
+    const std::string& name, std::vector<ConstantExpression*>* values)
+    : AnnotationParam(name), mValues(values) {}
+
+std::vector<std::string> ConstantExpressionAnnotationParam::getValues() const {
+    std::vector<std::string> ret;
+    for (const auto* ce : *mValues) {
+        ret.push_back(convertToString(ce));
+    };
+
+    return ret;
+}
+
+std::string ConstantExpressionAnnotationParam::getSingleValue() const {
+    CHECK_EQ(mValues->size(), 1u) << mName << " requires one value but has multiple";
+    return convertToString(mValues->at(0));
+}
+
+std::string ConstantExpressionAnnotationParam::convertToString(const ConstantExpression* ce) {
+    return ce->value() + " /* " + ce->description() + " */";
+}
+
+Annotation::Annotation(const char* name, AnnotationParamVector* params)
+    : mName(name), mParams(params) {}
+
 std::string Annotation::name() const {
     return mName;
 }
@@ -116,14 +128,14 @@
 
         out << param->getName() << "=";
 
-        const std::vector<std::string> *values = param->getValues();
-        if (values->size() > 1) {
+        const std::vector<std::string>& values = param->getValues();
+        if (values.size() > 1) {
             out << "{";
         }
 
-        out << StringHelper::JoinStrings(*values, ", ");
+        out << StringHelper::JoinStrings(values, ", ");
 
-        if (values->size() > 1) {
+        if (values.size() > 1) {
             out << "}";
         }
     }
diff --git a/Annotation.h b/Annotation.h
index 18d9ab0..776d723 100644
--- a/Annotation.h
+++ b/Annotation.h
@@ -29,15 +29,12 @@
 struct Formatter;
 
 struct AnnotationParam {
-    AnnotationParam(const std::string &name,
-                    std::vector<std::string> *values);
-    AnnotationParam(const std::string &name,
-                    std::vector<ConstantExpression *> *values);
+    virtual ~AnnotationParam() {}
 
-    const std::string &getName() const;
-    const std::vector<std::string> *getValues() const;
+    const std::string& getName() const;
 
-    const std::string &getSingleValue() const;
+    virtual std::vector<std::string> getValues() const = 0;
+    virtual std::string getSingleValue() const = 0;
 
     /* Returns unquoted version of getSingleValue */
     std::string getSingleString() const;
@@ -45,12 +42,36 @@
     /* Returns value interpretted as a boolean */
     bool getSingleBool() const;
 
-private:
+   protected:
     const std::string mName;
-    std::vector<std::string> *mValues;
+
+    AnnotationParam(const std::string& name);
 };
 
-using AnnotationParamVector = std::vector<const AnnotationParam*>;
+struct StringAnnotationParam : AnnotationParam {
+    StringAnnotationParam(const std::string& name, std::vector<std::string>* values);
+
+    std::vector<std::string> getValues() const override;
+    std::string getSingleValue() const override;
+
+   private:
+    std::vector<std::string>* const mValues;
+};
+
+struct ConstantExpressionAnnotationParam : AnnotationParam {
+    ConstantExpressionAnnotationParam(const std::string& name,
+                                      std::vector<ConstantExpression*>* values);
+
+    std::vector<std::string> getValues() const override;
+    std::string getSingleValue() const override;
+
+   private:
+    std::vector<ConstantExpression*>* const mValues;
+
+    static std::string convertToString(const ConstantExpression* ce);
+};
+
+using AnnotationParamVector = std::vector<AnnotationParam*>;
 
 struct Annotation {
     Annotation(const char *name, AnnotationParamVector *params);
diff --git a/Interface.cpp b/Interface.cpp
index 78d42ad..2acb5a0 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -838,7 +838,7 @@
                 const AnnotationParam *param =
                         annotation->getParam("next");
                 if (param != nullptr) {
-                    for (auto value : *param->getValues()) {
+                    for (const auto& value : param->getValues()) {
                         out << "next: " << value << "\n";
                     }
                 }
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 0a41664..5480ac3 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -391,11 +391,11 @@
 annotation_param
     : IDENTIFIER '=' annotation_string_value
       {
-          $$ = new AnnotationParam($1, $3);
+          $$ = new StringAnnotationParam($1, $3);
       }
     | IDENTIFIER '=' annotation_const_expr_value
       {
-          $$ = new AnnotationParam($1, $3);
+          $$ = new ConstantExpressionAnnotationParam($1, $3);
       }
     ;