Allow struct, union and enum type declarations to be annotated.

Change-Id: Idce594b47c324d8420638e2e8853da3c99150672
Bug: 31800672
Test: hidl_test, hidl_test_java
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 08ac6f0..0e7483e 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -105,6 +105,9 @@
 %type<type> enum_declaration
 %type<type> struct_or_union_declaration
 %type<type> opt_extends
+%type<type> type_declaration_body interface_declaration typedef_declaration
+%type<type> named_struct_or_union_declaration named_enum_declaration
+%type<type> compound_declaration annotated_compound_declaration
 
 %type<field> field_declaration
 %type<fields> field_declarations struct_or_union_body
@@ -329,41 +332,7 @@
     | EXTENDS fqtype { $$ = $2; }
 
 body
-    : opt_annotations INTERFACE IDENTIFIER opt_extends
-      {
-          if ($4 != NULL && !$4->isInterface()) {
-              std::cerr << "ERROR: You can only extend interfaces. at" << @4
-                        << "\n";
-
-              YYERROR;
-          }
-
-          if ($3[0] != 'I') {
-              std::cerr << "ERROR: All interface names must start with an 'I' "
-                        << "prefix. at " << @3 << "\n";
-
-              YYERROR;
-          }
-
-          Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
-
-          // Register interface immediately so it can be referenced inside
-          // definition.
-          std::string errorMsg;
-          if (!ast->addScopedType(iface, &errorMsg)) {
-              std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
-              YYERROR;
-          }
-
-          ast->enterScope(iface);
-      }
-      '{' interface_declarations '}' ';'
-      {
-          Interface *iface = static_cast<Interface *>(ast->scope());
-
-          ast->leaveScope();
-      }
-    | type_declarations
+    : type_declarations
     ;
 
 interface_declarations
@@ -382,9 +351,66 @@
     ;
 
 type_declaration
+    : opt_annotations type_declaration_body
+      {
+          if ($2 != nullptr) {
+              $2->setAnnotations($1);
+          } else if (!$1->empty()) {
+              // Since typedefs are always resolved to their target it makes
+              // little sense to annotate them and have their annotations
+              // impose semantics other than their target type.
+              std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
+                        << "\n";
+
+              YYERROR;
+          }
+      }
+    ;
+
+type_declaration_body
     : named_struct_or_union_declaration ';'
     | named_enum_declaration ';'
     | typedef_declaration ';'
+    | interface_declaration ';'
+    ;
+
+interface_declaration
+    : INTERFACE IDENTIFIER opt_extends
+      {
+          if ($3 != NULL && !$3->isInterface()) {
+              std::cerr << "ERROR: You can only extend interfaces. at" << @3
+                        << "\n";
+
+              YYERROR;
+          }
+
+          if ($2[0] != 'I') {
+              std::cerr << "ERROR: All interface names must start with an 'I' "
+                        << "prefix. at " << @2 << "\n";
+
+              YYERROR;
+          }
+
+          Interface *iface = new Interface($2, static_cast<Interface *>($3));
+
+          // Register interface immediately so it can be referenced inside
+          // definition.
+          std::string errorMsg;
+          if (!ast->addScopedType(iface, &errorMsg)) {
+              std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
+              YYERROR;
+          }
+
+          ast->enterScope(iface);
+      }
+      '{' interface_declarations '}'
+      {
+          Interface *iface = static_cast<Interface *>(ast->scope());
+
+          ast->leaveScope();
+
+          $$ = iface;
+      }
     ;
 
 typedef_declaration
@@ -395,6 +421,8 @@
               std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
               YYERROR;
           }
+
+          $$ = nullptr;
       }
     ;
 
@@ -525,6 +553,8 @@
               std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
               YYERROR;
           }
+
+          $$ = container;
       }
     ;
 
@@ -580,8 +610,20 @@
 
 field_declaration
     : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
-    | struct_or_union_declaration ';' { $$ = NULL; }
-    | enum_declaration ';' { $$ = NULL; }
+    | annotated_compound_declaration ';' { $$ = NULL; }
+    ;
+
+annotated_compound_declaration
+    : opt_annotations compound_declaration
+      {
+          $2->setAnnotations($1);
+          $$ = $2;
+      }
+    ;
+
+compound_declaration
+    : struct_or_union_declaration { $$ = $1; }
+    | enum_declaration { $$ = $1; }
     ;
 
 opt_storage_type
@@ -619,6 +661,8 @@
               std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
               YYERROR;
           }
+
+          $$ = enumType;
       }
     ;
 
@@ -712,8 +756,7 @@
 
           $$ = new VectorType($3);
       }
-    | struct_or_union_declaration { $$ = $1; }
-    | enum_declaration { $$ = $1; }
+    | annotated_compound_declaration { $$ = $1; }
     | INTERFACE { $$ = new GenericBinder; }
     ;