Refactor constant declarations.

In preparation for default values for parcelable members.

Bug: 110758329
Test: boot Pixel 2
Test: runtests.sh
Change-Id: Id9c3f6b2242d66e69206c17cabfd61f8921d40b7
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 4da3e79..4cb3aa7 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -189,45 +189,72 @@
   return GetDirectionSpecifier() + AidlVariableDeclaration::Signature();
 }
 
-AidlIntConstant::AidlIntConstant(std::string name, int32_t value)
-    : name_(name),
-      value_(value),
-      is_valid_(true) {}
-
-AidlIntConstant::AidlIntConstant(std::string name,
-                                 std::string value,
-                                 unsigned line_number)
-    : name_(name) {
-  uint32_t unsigned_val;
-  if (!android::base::ParseUint(value.c_str(), &unsigned_val)) {
-    is_valid_ = false;
-    LOG(ERROR) << "Found invalid int value '" << value
-               << "' on line " << line_number;
-  } else {
-    // Converting from unsigned to signed integer.
-    value_ = unsigned_val;
-    is_valid_ = true;
+string AidlConstantValue::ToString(Type type) {
+  switch (type) {
+    case Type::INTEGER:
+      return "int";
+    case Type::STRING:
+      return "String";
+    case Type::ERROR:
+      LOG(FATAL) << "aidl internal error: error type failed to halt program";
+    default:
+      LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
+      return "";  // not reached
   }
 }
 
-AidlStringConstant::AidlStringConstant(std::string name,
-                                       std::string value,
-                                       unsigned line_number)
-    : name_(name),
-      value_(value) {
-  is_valid_ = true;
-  for (size_t i = 0; i < value_.length(); ++i) {
-    const char& c = value_[i];
+AidlConstantValue::AidlConstantValue(Type type, const std::string& checked_value)
+    : type_(type), value_(checked_value) {}
+
+AidlConstantValue* AidlConstantValue::LiteralInt(int32_t value) {
+  return new AidlConstantValue(Type::INTEGER, std::to_string(value));
+}
+
+AidlConstantValue* AidlConstantValue::ParseHex(const std::string& value, unsigned line) {
+  uint32_t unsigned_value;
+  if (!android::base::ParseUint<uint32_t>(value.c_str(), &unsigned_value)) {
+    cerr << "Found invalid int value '" << value << "' on line " << line << endl;
+    return new AidlConstantValue(Type::ERROR, "");
+  }
+
+  return LiteralInt(unsigned_value);
+}
+
+AidlConstantValue* AidlConstantValue::ParseString(const std::string& value, unsigned line) {
+  for (size_t i = 0; i < value.length(); ++i) {
+    const char& c = value[i];
     if (c <= 0x1f || // control characters are < 0x20
         c >= 0x7f || // DEL is 0x7f
         c == '\\') { // Disallow backslashes for future proofing.
-      LOG(ERROR) << "Found invalid character at index " << i
-                 << " in string constant '" << value_
-                 << "' beginning on line " << line_number;
-      is_valid_ = false;
-      break;
+      cerr << "Found invalid character at index " << i << " in string constant '" << value
+           << "' beginning on line " << line << endl;
+      return new AidlConstantValue(Type::ERROR, "");
     }
   }
+
+  return new AidlConstantValue(Type::STRING, value);
+}
+
+string AidlConstantValue::ToString() const {
+  CHECK(type_ != Type::ERROR) << "aidl internal error: error should be checked " << value_;
+  return value_;
+}
+
+AidlConstantDeclaration::AidlConstantDeclaration(AidlTypeSpecifier* type, std::string name,
+                                                 AidlConstantValue* value, unsigned line)
+    : type_(type), name_(name), value_(value), line_(line) {}
+
+bool AidlConstantDeclaration::CheckValid() const {
+  // Error message logged above
+  if (value_->GetType() == AidlConstantValue::Type::ERROR) return false;
+
+  if (type_->ToString() != AidlConstantValue::ToString(value_->GetType())) {
+    cerr << "Constant " << name_ << " is of type " << type_->ToString() << " but value is of type "
+         << AidlConstantValue::ToString(value_->GetType()) << " on line " << line_ << endl;
+    return false;
+  }
+
+  return true;
 }
 
 AidlMethod::AidlMethod(bool oneway, AidlTypeSpecifier* type, std::string name,
@@ -323,15 +350,14 @@
   for (auto& member : *members) {
     AidlMember* local = member.release();
     AidlMethod* method = local->AsMethod();
-    AidlIntConstant* int_constant = local->AsIntConstant();
-    AidlStringConstant* string_constant = local->AsStringConstant();
+    AidlConstantDeclaration* constant = local->AsConstantDeclaration();
+
+    CHECK(method == nullptr || constant == nullptr);
 
     if (method) {
       methods_.emplace_back(method);
-    } else if (int_constant) {
-      int_constants_.emplace_back(int_constant);
-    } else if (string_constant) {
-      string_constants_.emplace_back(string_constant);
+    } else if (constant) {
+      constants_.emplace_back(constant);
     } else {
       LOG(FATAL) << "Member is neither method nor constant!";
     }