hidl-gen: warnings for bad annotations

hidl-gen never paid attention to annotations, and we can see in-tree
that there are some annotatoins which don't do anything.

Warnings instead of errors, since it doesn't make sense to break
downstream (might enable them after a long time if it became more
important).

Bug: 173732508
Test: build/test with adding errors to cleanup AOSP interfaces
Change-Id: I5b68a25f5e39239b2061c0e5186710f5cbf12c22
diff --git a/EnumType.cpp b/EnumType.cpp
index 937f147..31835b3 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -111,6 +111,22 @@
     return Scope::validate();
 }
 
+status_t EnumType::validateAnnotations() const {
+    for (const Annotation* annotation : annotations()) {
+        const std::string name = annotation->name();
+
+        if (name == "export") {
+            continue;
+        }
+
+        std::cerr << "WARNING: Unrecognized annotation '" << name << "' for " << typeName()
+                  << " at " << location() << ". Only @export is supported." << std::endl;
+        // This is a warning to avoid breaking downstream unnecessarily.
+        // return UNKNOWN_ERROR;
+    }
+    return OK;
+}
+
 status_t EnumType::validateUniqueNames() const {
     std::unordered_map<std::string, const EnumType*> registeredValueNames;
     for (const auto* type : superTypeChain()) {
diff --git a/EnumType.h b/EnumType.h
index 2093c37..fa31e4a 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -74,6 +74,7 @@
 
     status_t resolveInheritance() override;
     status_t validate() const override;
+    status_t validateAnnotations() const override;
     status_t validateUniqueNames() const;
 
     void emitJavaFieldInitializer(Formatter&, const std::string&) const override;
diff --git a/Interface.cpp b/Interface.cpp
index c666876..1307a0b 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -490,9 +490,6 @@
     err = validateUniqueNames();
     if (err != OK) return err;
 
-    err = validateAnnotations();
-    if (err != OK) return err;
-
     return Scope::validate();
 }
 
@@ -536,6 +533,19 @@
 }
 
 status_t Interface::validateAnnotations() const {
+    for (const Annotation* annotation : annotations()) {
+        const std::string name = annotation->name();
+
+        if (name == "SensitiveData") {
+            continue;
+        }
+
+        std::cerr << "WARNING: Unrecognized annotation '" << name << "' for " << typeName()
+                  << " at " << location() << ". Only @SensitiveData is supported." << std::endl;
+        // ideally would be error, but we don't want to break downstream
+        // return UNKNOWN_ERROR;
+    }
+
     for (const Method* method : methods()) {
         for (const Annotation* annotation : method->annotations()) {
             const std::string name = annotation->name();
@@ -545,12 +555,13 @@
             }
 
             std::cerr << "ERROR: Unrecognized annotation '" << name
-                      << "' for method: " << method->name() << ". An annotation should be one of: "
-                      << "entry, exit, callflow." << std::endl;
+                      << "' for method: " << method->name() << " at " << method->location()
+                      << ". An annotation should be one of: "
+                      << "@entry, @exit, or @callflow." << std::endl;
             return UNKNOWN_ERROR;
         }
     }
-    return OK;
+    return OK;  // not calling superclass which is more restrictive
 }
 
 bool Interface::addAllReservedMethods(const std::map<std::string, Method*>& allReservedMethods) {
diff --git a/Interface.h b/Interface.h
index 0a27a00..ea28757 100644
--- a/Interface.h
+++ b/Interface.h
@@ -106,7 +106,7 @@
     status_t resolveInheritance() override;
     status_t validate() const override;
     status_t validateUniqueNames() const;
-    status_t validateAnnotations() const;
+    status_t validateAnnotations() const override;
 
     void emitReaderWriter(
             Formatter &out,
diff --git a/Scope.cpp b/Scope.cpp
index 588ba95..026a7ac 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -41,6 +41,13 @@
     mTypeIndexByName[type->definedName()] = index;
 }
 
+status_t Scope::validate() const {
+    status_t status = validateAnnotations();
+    if (status != OK) return status;
+
+    return NamedType::validate();
+}
+
 status_t Scope::validateUniqueNames() const {
     for (const auto* type : mTypes) {
         if (mTypes[mTypeIndexByName.at(type->definedName())] != type) {
@@ -52,6 +59,15 @@
     return OK;
 }
 
+status_t Scope::validateAnnotations() const {
+    for (const Annotation* annotation : annotations()) {
+        std::cerr << "WARNING: Unrecognized annotation '" << annotation->name() << "' at "
+                  << location() << ". No annotations are supported here." << std::endl;
+        // This is a warning to avoid breaking downstream unnecessarily.
+    }
+    return OK;
+}
+
 NamedType *Scope::lookupType(const FQName &fqName) const {
     CHECK(fqName.package().empty() && fqName.version().empty());
     if (!fqName.valueName().empty()) {
diff --git a/Scope.h b/Scope.h
index ea6ef2b..d67a300 100644
--- a/Scope.h
+++ b/Scope.h
@@ -40,6 +40,9 @@
 
     void addType(NamedType* type);
 
+    status_t validate() const override;
+    virtual status_t validateAnnotations() const;
+
     status_t validateUniqueNames() const;
 
     // lookup a type given an FQName.