Do all validation during validation phase.

When hidl-gen was originally written, validation occured
at two different times: parsing and generation.

Since then, hidl-gen was re-written to be a multi-pass compiler.
The basic phases are now (see main + AST::postParse):
  parse, process, validate, generate

However, some validation still exists during the generation phase.
This validation code has been gradually cleaned up, but, here, I am
cleaning up all the rest.

By moving the code to validation, we are fixing several classes
of problems:
1. generate functions almost exclusively (except for the few exceptions
   that this CL cleans up) always return status OK. We have a bunch of
   data flow logic which exists solely to propagate "return OK". This
   is just plain silly.
2. a large number of the returns from emit/generate functions are not
   actually checked. We've had a several bugs from this and also many
   CLs just to fix this when they've been discovered. This causes problems
   where hidl-gen fails but nothing notices.
3. sometimes files are written before things are validated. This is
   extremely frustrating and also the cause of other bugs. One common
   case of this (while developing) is when updating makefiles, the hidl-gen
   compiler complains something is wrong with an interface, but it has
   already partially written new but invalid makefiles. This means that
   they have to be manually fixed before another build can begin.
4. having status_t returns from generate functions indicates to someone
   working on hidl-gen that they can return an error here, but they
   should always return an error from the correct validation function.
   Removing the ability to return ERROR makes sure that new errors are
   caught/validated in the correct place. One instance in this CL of
   this happening is that annotations are also checked on isHidlReserved
   methods whereas before, these were incorrectly only checked on regular
   methods.

(note, breaking text to avoid pinging these)
B ug: 65636464 (forward declarations, made this possible)
B ug: 34807779 (better tools for java compatibility, closer to being solved)
B ug: 32573681 (instance of 2 above).

Test: hidl's run_all_host_tests.sh
Change-Id: I8988e1fdf16e15b925c0a613122c41e6a41bd4dd
diff --git a/AST.h b/AST.h
index f966bff..5987eb1 100644
--- a/AST.h
+++ b/AST.h
@@ -119,24 +119,24 @@
 
     status_t gatherReferencedTypes();
 
-    status_t generateCppSource(Formatter& out) const;
+    void generateCppSource(Formatter& out) const;
 
-    status_t generateInterfaceHeader(Formatter& out) const;
-    status_t generateHwBinderHeader(Formatter& out) const;
-    status_t generateStubHeader(Formatter& out) const;
-    status_t generateProxyHeader(Formatter& out) const;
-    status_t generatePassthroughHeader(Formatter& out) const;
+    void generateInterfaceHeader(Formatter& out) const;
+    void generateHwBinderHeader(Formatter& out) const;
+    void generateStubHeader(Formatter& out) const;
+    void generateProxyHeader(Formatter& out) const;
+    void generatePassthroughHeader(Formatter& out) const;
 
-    status_t generateCppImplHeader(Formatter& out) const;
-    status_t generateCppImplSource(Formatter& out) const;
+    void generateCppImplHeader(Formatter& out) const;
+    void generateCppImplSource(Formatter& out) const;
 
-    status_t generateCppAdapterHeader(Formatter& out) const;
-    status_t generateCppAdapterSource(Formatter& out) const;
+    void generateCppAdapterHeader(Formatter& out) const;
+    void generateCppAdapterSource(Formatter& out) const;
 
-    status_t generateJava(Formatter& out, const std::string& limitToType) const;
-    status_t generateJavaTypes(Formatter& out, const std::string& limitToType) const;
+    void generateJava(Formatter& out, const std::string& limitToType) const;
+    void generateJavaTypes(Formatter& out, const std::string& limitToType) const;
 
-    status_t generateVts(Formatter& out) const;
+    void generateVts(Formatter& out) const;
 
     void getImportedPackages(std::set<FQName> *importSet) const;
 
@@ -252,52 +252,41 @@
 
     static void generateCheckNonNull(Formatter &out, const std::string &nonNull);
 
-    status_t generateTypeSource(
-            Formatter &out, const std::string &ifaceName) const;
+    void generateTypeSource(Formatter& out, const std::string& ifaceName) const;
 
     // a method, and in which interface is it originally defined.
     // be careful of the case where method.isHidlReserved(), where interface
     // is effectively useless.
-    using MethodGenerator = std::function<status_t(const Method *, const Interface *)>;
+    using MethodGenerator = std::function<void(const Method*, const Interface*)>;
 
     void generateTemplatizationLink(Formatter& out) const;
     void generateCppTag(Formatter& out, const std::string& tag) const;
 
-    status_t generateMethods(Formatter &out,
-                             const MethodGenerator &gen,
-                             bool includeParents = true) const;
-    status_t generateStubImplMethod(Formatter &out,
-                                    const std::string &className,
-                                    const Method *method) const;
-    status_t generatePassthroughMethod(Formatter &out,
-                                       const Method *method) const;
-    status_t generateStaticProxyMethodSource(Formatter &out,
-                                             const std::string &className,
-                                             const Method *method) const;
-    status_t generateProxyMethodSource(Formatter &out,
-                                       const std::string &className,
-                                       const Method *method,
-                                       const Interface *superInterface) const;
+    void generateMethods(Formatter& out, const MethodGenerator& gen,
+                         bool includeParents = true) const;
+    void generateStubImplMethod(Formatter& out, const std::string& className,
+                                const Method* method) const;
+    void generatePassthroughMethod(Formatter& out, const Method* method) const;
+    void generateStaticProxyMethodSource(Formatter& out, const std::string& className,
+                                         const Method* method) const;
+    void generateProxyMethodSource(Formatter& out, const std::string& className,
+                                   const Method* method, const Interface* superInterface) const;
     void generateAdapterMethod(Formatter& out, const Method* method) const;
 
     void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const;
 
-    status_t generateProxySource(
-            Formatter &out, const FQName &fqName) const;
+    void generateProxySource(Formatter& out, const FQName& fqName) const;
 
-    status_t generateStubSource(
-            Formatter &out, const Interface *iface) const;
+    void generateStubSource(Formatter& out, const Interface* iface) const;
 
-    status_t generateStubSourceForMethod(Formatter &out,
-                                         const Method *method,
-                                         const Interface *superInterface) const;
-    status_t generateStaticStubMethodSource(Formatter &out,
-                                            const FQName &fqName,
-                                            const Method *method) const;
+    void generateStubSourceForMethod(Formatter& out, const Method* method,
+                                     const Interface* superInterface) const;
+    void generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
+                                        const Method* method) const;
 
-    status_t generatePassthroughSource(Formatter &out) const;
+    void generatePassthroughSource(Formatter& out) const;
 
-    status_t generateInterfaceSource(Formatter &out) const;
+    void generateInterfaceSource(Formatter& out) const;
 
     enum InstrumentationEvent {
         SERVER_API_ENTRY = 0,
@@ -337,9 +326,9 @@
                               const NamedReference<Type>* arg, bool isReader,
                               bool addPrefixToName) const;
 
-    status_t emitTypeDeclarations(Formatter &out) const;
-    status_t emitJavaTypeDeclarations(Formatter &out) const;
-    status_t emitVtsTypeDeclarations(Formatter &out) const;
+    void emitTypeDeclarations(Formatter& out) const;
+    void emitJavaTypeDeclarations(Formatter& out) const;
+    void emitVtsTypeDeclarations(Formatter& out) const;
 
     DISALLOW_COPY_AND_ASSIGN(AST);
 };
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 9cd6471..5155a27 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -558,17 +558,14 @@
     out << "}\n";
 }
 
-status_t ArrayType::emitVtsTypeDeclarations(Formatter &out) const {
+void ArrayType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << "vector_size: " << mSizes[0]->value() << "\n";
     out << "vector_value: {\n";
     out.indent();
     // Simple array case.
     if (mSizes.size() == 1) {
-        status_t err = mElementType->emitVtsTypeDeclarations(out);
-        if (err != OK) {
-            return err;
-        }
+        mElementType->emitVtsTypeDeclarations(out);
     } else {  // Multi-dimension array case.
         for (size_t index = 1; index < mSizes.size(); index++) {
             out << "type: " << getVtsType() << "\n";
@@ -576,10 +573,7 @@
             out << "vector_value: {\n";
             out.indent();
             if (index == mSizes.size() - 1) {
-                status_t err = mElementType->emitVtsTypeDeclarations(out);
-                if (err != OK) {
-                    return err;
-                }
+                mElementType->emitVtsTypeDeclarations(out);
             }
         }
     }
@@ -587,7 +581,6 @@
         out.unindent();
         out << "}\n";
     }
-    return OK;
 }
 
 bool ArrayType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
diff --git a/ArrayType.h b/ArrayType.h
index 378953b..2c13a33 100644
--- a/ArrayType.h
+++ b/ArrayType.h
@@ -130,7 +130,7 @@
             const std::string &offset,
             bool isReader) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 
     bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const override;
     bool deepContainsPointer(std::unordered_set<const Type*>* visited) const override;
diff --git a/CompoundType.cpp b/CompoundType.cpp
index c019edb..64ec2c2 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -374,7 +374,7 @@
     handleError(out, mode);
 }
 
-status_t CompoundType::emitTypeDeclarations(Formatter &out) const {
+void CompoundType::emitTypeDeclarations(Formatter& out) const {
     out << ((mStyle == STYLE_STRUCT) ? "struct" : "union")
         << " "
         << localName()
@@ -395,7 +395,7 @@
         out.unindent();
         out << "};\n\n";
 
-        return OK;
+        return;
     }
 
     for (int pass = 0; pass < 2; ++pass) {
@@ -451,15 +451,13 @@
         << ") == "
         << structAlign
         << ", \"wrong alignment\");\n\n";
-
-    return OK;
 }
 
 void CompoundType::emitTypeForwardDeclaration(Formatter& out) const {
     out << ((mStyle == STYLE_STRUCT) ? "struct" : "union") << " " << localName() << ";\n";
 }
 
-status_t CompoundType::emitPackageTypeDeclarations(Formatter& out) const {
+void CompoundType::emitPackageTypeDeclarations(Formatter& out) const {
     Scope::emitPackageTypeDeclarations(out);
 
     // TODO(b/65200821): remove these ifdefs
@@ -520,11 +518,9 @@
         out << "// operator== and operator!= are not generated for " << localName() << "\n\n";
     }
     out << "#endif  // REALLY_IS_HIDL_INTERNAL_LIB\n";
-
-    return OK;
 }
 
-status_t CompoundType::emitPackageHwDeclarations(Formatter& out) const {
+void CompoundType::emitPackageHwDeclarations(Formatter& out) const {
     if (needsEmbeddedReadWrite()) {
         out << "::android::status_t readEmbeddedFromParcel(\n";
 
@@ -563,17 +559,11 @@
             << "size_t parentHandle, size_t parentOffset);\n\n";
         out.unindent(2);
     }
-
-    return OK;
 }
 
-status_t CompoundType::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
+void CompoundType::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
     std::string space = prefix.empty() ? "" : (prefix + "::");
-    status_t err = Scope::emitTypeDefinitions(out, space + localName());
-
-    if (err != OK) {
-        return err;
-    }
+    Scope::emitTypeDefinitions(out, space + localName());
 
     if (needsEmbeddedReadWrite()) {
         emitStructReaderWriter(out, prefix, true /* isReader */);
@@ -631,12 +621,9 @@
     } else {
         out << "// operator== and operator!= are not generated for " << localName() << "\n";
     }
-
-    return OK;
 }
 
-status_t CompoundType::emitJavaTypeDeclarations(
-        Formatter &out, bool atTopLevel) const {
+void CompoundType::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
     out << "public final ";
 
     if (!atTopLevel) {
@@ -871,8 +858,6 @@
 
     out.unindent();
     out << "};\n\n";
-
-    return OK;
 }
 
 void CompoundType::emitStructReaderWriter(
@@ -1054,7 +1039,7 @@
     return !containsInterface() ;
 }
 
-status_t CompoundType::emitVtsTypeDeclarations(Formatter &out) const {
+void CompoundType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "name: \"" << fullName() << "\"\n";
     out << "type: " << getVtsType() << "\n";
 
@@ -1073,10 +1058,7 @@
             }
         }
         out.indent();
-        status_t status(type->emitVtsTypeDeclarations(out));
-        if (status != OK) {
-            return status;
-        }
+        type->emitVtsTypeDeclarations(out);
         out.unindent();
         out << "}\n";
     }
@@ -1097,21 +1079,15 @@
         }
         out.indent();
         out << "name: \"" << field->name() << "\"\n";
-        status_t status = field->type().emitVtsAttributeType(out);
-        if (status != OK) {
-            return status;
-        }
+        field->type().emitVtsAttributeType(out);
         out.unindent();
         out << "}\n";
     }
-
-    return OK;
 }
 
-status_t CompoundType::emitVtsAttributeType(Formatter &out) const {
+void CompoundType::emitVtsAttributeType(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << "predefined_type: \"" << fullName() << "\"\n";
-    return OK;
 }
 
 bool CompoundType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
diff --git a/CompoundType.h b/CompoundType.h
index 2348814..3ef5f02 100644
--- a/CompoundType.h
+++ b/CompoundType.h
@@ -117,22 +117,21 @@
             const std::string &offset,
             bool isReader) const override;
 
-    status_t emitTypeDeclarations(Formatter &out) const override;
+    void emitTypeDeclarations(Formatter& out) const override;
     void emitTypeForwardDeclaration(Formatter& out) const override;
-    status_t emitPackageTypeDeclarations(Formatter& out) const override;
-    status_t emitPackageHwDeclarations(Formatter& out) const override;
+    void emitPackageTypeDeclarations(Formatter& out) const override;
+    void emitPackageHwDeclarations(Formatter& out) const override;
 
-    status_t emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
+    void emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
 
-    status_t emitJavaTypeDeclarations(
-            Formatter &out, bool atTopLevel) const override;
+    void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const override;
 
     bool needsEmbeddedReadWrite() const override;
     bool deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const override;
     bool resultNeedsDeref() const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
-    status_t emitVtsAttributeType(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
+    void emitVtsAttributeType(Formatter& out) const override;
 
     bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const override;
     bool deepContainsPointer(std::unordered_set<const Type*>* visited) const override;
diff --git a/DeathRecipientType.cpp b/DeathRecipientType.cpp
index 1bd3d3c..abc69fc 100644
--- a/DeathRecipientType.cpp
+++ b/DeathRecipientType.cpp
@@ -78,9 +78,8 @@
     *align = *size = 0; // this object should only be used in passthrough mode
 }
 
-status_t DeathRecipientType::emitVtsTypeDeclarations(Formatter &out) const {
+void DeathRecipientType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
-    return OK;
 }
 
 }  // namespace android
diff --git a/DeathRecipientType.h b/DeathRecipientType.h
index 9e18c1e..a7213cd 100644
--- a/DeathRecipientType.h
+++ b/DeathRecipientType.h
@@ -47,7 +47,7 @@
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 };
 
 }  // namespace android
diff --git a/EnumType.cpp b/EnumType.cpp
index bbed7cd..4da3c03 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -234,7 +234,7 @@
             out, depth, parcelName, blobName, fieldName, offset, isReader);
 }
 
-status_t EnumType::emitTypeDeclarations(Formatter &out) const {
+void EnumType::emitTypeDeclarations(Formatter& out) const {
     const ScalarType *scalarType = mStorageType->resolveToScalarType();
     CHECK(scalarType != nullptr);
 
@@ -273,8 +273,6 @@
 
     out.unindent();
     out << "};\n\n";
-
-    return OK;
 }
 
 void EnumType::emitTypeForwardDeclaration(Formatter& out) const {
@@ -388,7 +386,7 @@
     out << "}  // namespace android\n";
 }
 
-status_t EnumType::emitPackageTypeDeclarations(Formatter& out) const {
+void EnumType::emitPackageTypeDeclarations(Formatter& out) const {
     emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
     emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
     emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "|");
@@ -469,11 +467,9 @@
         out << "return os;\n";
     }).endl().endl();
     out << "#endif  // REALLY_IS_HIDL_INTERNAL_LIB\n";
-
-    return OK;
 }
 
-status_t EnumType::emitTypeDefinitions(Formatter& out, const std::string& /* prefix */) const {
+void EnumType::emitTypeDefinitions(Formatter& out, const std::string& /* prefix */) const {
     // TODO(b/65200821): remove toString from .cpp once all prebuilts are rebuilt
 
     const ScalarType *scalarType = mStorageType->resolveToScalarType();
@@ -531,11 +527,9 @@
             "static_cast<" + scalarType->getCppStackType() + ">(o)");
         out << "return os;\n";
     }).endl().endl();
-
-    return OK;
 }
 
-status_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool atTopLevel) const {
+void EnumType::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
     const ScalarType *scalarType = mStorageType->resolveToScalarType();
     CHECK(scalarType != NULL);
 
@@ -620,11 +614,9 @@
 
     out.unindent();
     out << "};\n\n";
-
-    return OK;
 }
 
-status_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
+void EnumType::emitVtsTypeDeclarations(Formatter& out) const {
     const ScalarType *scalarType = mStorageType->resolveToScalarType();
 
     out << "name: \"" << fullName() << "\"\n";
@@ -658,13 +650,11 @@
 
     out.unindent();
     out << "}\n";
-    return OK;
 }
 
-status_t EnumType::emitVtsAttributeType(Formatter &out) const {
+void EnumType::emitVtsAttributeType(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << "predefined_type: \"" << fullName() << "\"\n";
-    return OK;
 }
 
 void EnumType::emitJavaDump(
@@ -720,7 +710,7 @@
     }
 }
 
-status_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
+void EnumType::emitExportedHeader(Formatter& out, bool forJava) const {
     const Annotation *annotation = findExportAnnotation();
     CHECK(annotation != nullptr);
 
@@ -807,7 +797,7 @@
         }
         out << "\n";
 
-        return OK;
+        return;
     }
 
     if (!name.empty()) {
@@ -847,8 +837,6 @@
     }
 
     out << ";\n\n";
-
-    return OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -968,14 +956,13 @@
     return resolveToScalarType()->canCheckEquality(visited);
 }
 
-status_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
+void BitFieldType::emitVtsAttributeType(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << "scalar_type: \""
         << mElementType->resolveToScalarType()->getVtsScalarType()
         << "\"\n";
     out << "predefined_type: \"" << static_cast<const NamedType*>(mElementType.get())->fullName()
         << "\"\n";
-    return OK;
 }
 
 void BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
diff --git a/EnumType.h b/EnumType.h
index 7e7a6dc..ca0374e 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -90,17 +90,16 @@
             const std::string &offset,
             bool isReader) const override;
 
-    status_t emitTypeDeclarations(Formatter &out) const override;
+    void emitTypeDeclarations(Formatter& out) const override;
     void emitTypeForwardDeclaration(Formatter& out) const override;
     void emitGlobalTypeDeclarations(Formatter& out) const override;
-    status_t emitPackageTypeDeclarations(Formatter& out) const override;
-    status_t emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
+    void emitPackageTypeDeclarations(Formatter& out) const override;
+    void emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
 
-    status_t emitJavaTypeDeclarations(
-            Formatter &out, bool atTopLevel) const override;
+    void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
-    status_t emitVtsAttributeType(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
+    void emitVtsAttributeType(Formatter& out) const override;
 
     void emitJavaDump(
             Formatter &out,
@@ -112,7 +111,7 @@
     void appendToExportedTypesVector(
             std::vector<const Type *> *exportedTypes) const override;
 
-    status_t emitExportedHeader(Formatter &out, bool forJava) const override;
+    void emitExportedHeader(Formatter& out, bool forJava) const override;
 
    private:
     std::vector<const EnumType*> typeChain() const;
@@ -194,7 +193,7 @@
 
     const EnumType* getEnumType() const;
 
-    status_t emitVtsAttributeType(Formatter &out) const override;
+    void emitVtsAttributeType(Formatter& out) const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 
diff --git a/HandleType.cpp b/HandleType.cpp
index 9b937c9..7b6545d 100644
--- a/HandleType.cpp
+++ b/HandleType.cpp
@@ -167,9 +167,8 @@
     *size = assertion.size();
 }
 
-status_t HandleType::emitVtsTypeDeclarations(Formatter &out) const {
+void HandleType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
-    return OK;
 }
 
 }  // namespace android
diff --git a/HandleType.h b/HandleType.h
index 754aad7..feaddb0 100644
--- a/HandleType.h
+++ b/HandleType.h
@@ -64,7 +64,7 @@
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 };
 
 }  // namespace android
diff --git a/Interface.cpp b/Interface.cpp
index 7d2c83c..bf1690f 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -532,7 +532,12 @@
         return UNKNOWN_ERROR;
     }
 
-    status_t err = validateUniqueNames();
+    status_t err;
+
+    err = validateUniqueNames();
+    if (err != OK) return err;
+
+    err = validateAnnotations();
     if (err != OK) return err;
 
     return Scope::validate();
@@ -577,6 +582,24 @@
     return OK;
 }
 
+status_t Interface::validateAnnotations() const {
+    for (const Method* method : methods()) {
+        for (const Annotation* annotation : method->annotations()) {
+            const std::string name = annotation->name();
+
+            if (name == "entry" || name == "exit" || name == "callflow") {
+                continue;
+            }
+
+            std::cerr << "ERROR: Unrecognized annotation '" << name
+                      << "' for method: " << method->name() << ". An annotation should be one of: "
+                      << "entry, exit, callflow." << std::endl;
+            return UNKNOWN_ERROR;
+        }
+    }
+    return OK;
+}
+
 bool Interface::addAllReservedMethods() {
     // use a sorted map to insert them in serial ID order.
     std::map<int32_t, Method *> reservedMethodsById;
@@ -823,11 +846,8 @@
     }
 }
 
-status_t Interface::emitPackageTypeDeclarations(Formatter& out) const {
-    status_t status = Scope::emitPackageTypeDeclarations(out);
-    if (status != OK) {
-        return status;
-    }
+void Interface::emitPackageTypeDeclarations(Formatter& out) const {
+    Scope::emitPackageTypeDeclarations(out);
 
     // TODO(b/65200821): remove these ifndefs
     out << "#ifdef REALLY_IS_HIDL_INTERNAL_LIB" << gCurrentCompileName << "\n";
@@ -845,16 +865,11 @@
             << "return os;\n";
     }).endl().endl();
     out << "#endif  // REALLY_IS_HIDL_INTERNAL_LIB\n";
-
-    return OK;
 }
 
-status_t Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
+void Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
     std::string space = prefix.empty() ? "" : (prefix + "::");
-    status_t err = Scope::emitTypeDefinitions(out, space + localName());
-    if (err != OK) {
-        return err;
-    }
+    Scope::emitTypeDefinitions(out, space + localName());
 
     // TODO(b/65200821): remove toString from .cpp once all prebuilts are rebuilt
     out << "std::string toString("
@@ -868,8 +883,6 @@
             << "os += o->isRemote() ? \"@remote\" : \"@local\";\n"
             << "return os;\n";
     }).endl().endl();
-
-    return OK;
 }
 
 void Interface::emitJavaReaderWriter(
@@ -892,7 +905,7 @@
     }
 }
 
-status_t Interface::emitVtsAttributeDeclaration(Formatter &out) const {
+void Interface::emitVtsAttributeDeclaration(Formatter& out) const {
     for (const auto &type : getSubTypes()) {
         // Skip for TypeDef as it is just an alias of a defined type.
         if (type->isTypeDef()) {
@@ -900,17 +913,13 @@
         }
         out << "attribute: {\n";
         out.indent();
-        status_t status = type->emitVtsTypeDeclarations(out);
-        if (status != OK) {
-            return status;
-        }
+        type->emitVtsTypeDeclarations(out);
         out.unindent();
         out << "}\n\n";
     }
-    return OK;
 }
 
-status_t Interface::emitVtsMethodDeclaration(Formatter &out) const {
+void Interface::emitVtsMethodDeclaration(Formatter& out) const {
     for (const auto &method : methods()) {
         if (method->isHidlReserved()) {
             continue;
@@ -923,10 +932,7 @@
         for (const auto &result : method->results()) {
             out << "return_type_hidl: {\n";
             out.indent();
-            status_t status = result->type().emitVtsAttributeType(out);
-            if (status != OK) {
-                return status;
-            }
+            result->type().emitVtsAttributeType(out);
             out.unindent();
             out << "}\n";
         }
@@ -934,10 +940,7 @@
         for (const auto &arg : method->args()) {
             out << "arg: {\n";
             out.indent();
-            status_t status = arg->type().emitVtsAttributeType(out);
-            if (status != OK) {
-                return status;
-            }
+            arg->type().emitVtsAttributeType(out);
             out.unindent();
             out << "}\n";
         }
@@ -945,7 +948,7 @@
         for (const auto &annotation : method->annotations()) {
             out << "callflow: {\n";
             out.indent();
-            std::string name = annotation->name();
+            const std::string name = annotation->name();
             if (name == "entry") {
                 out << "entry: true\n";
             } else if (name == "exit") {
@@ -959,11 +962,7 @@
                     }
                 }
             } else {
-                std::cerr << "ERROR: Unrecognized annotation '" << name
-                          << "' for method: " << method->name()
-                          << ". A VTS annotation should be one of: "
-                          << "entry, exit, callflow." << std::endl;
-                return UNKNOWN_ERROR;
+                CHECK(false);
             }
             out.unindent();
             out << "}\n";
@@ -971,15 +970,13 @@
         out.unindent();
         out << "}\n\n";
     }
-    return OK;
 }
 
-status_t Interface::emitVtsAttributeType(Formatter &out) const {
+void Interface::emitVtsAttributeType(Formatter& out) const {
     out << "type: " << getVtsType() << "\n"
         << "predefined_type: \""
         << fullName()
         << "\"\n";
-    return OK;
 }
 
 bool Interface::hasOnewayMethods() const {
diff --git a/Interface.h b/Interface.h
index becdd16..0c94c0c 100644
--- a/Interface.h
+++ b/Interface.h
@@ -104,6 +104,7 @@
     status_t resolveInheritance() override;
     status_t validate() const override;
     status_t validateUniqueNames() const;
+    status_t validateAnnotations() const;
 
     void emitReaderWriter(
             Formatter &out,
@@ -113,8 +114,8 @@
             bool isReader,
             ErrorMode mode) const override;
 
-    status_t emitPackageTypeDeclarations(Formatter& out) const override;
-    status_t emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
+    void emitPackageTypeDeclarations(Formatter& out) const override;
+    void emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
 
     void getAlignmentAndSize(size_t* align, size_t* size) const override;
     void emitJavaReaderWriter(
@@ -123,10 +124,10 @@
             const std::string &argName,
             bool isReader) const override;
 
-    status_t emitVtsAttributeType(Formatter &out) const override;
+    void emitVtsAttributeType(Formatter& out) const override;
 
-    status_t emitVtsAttributeDeclaration(Formatter &out) const;
-    status_t emitVtsMethodDeclaration(Formatter &out) const;
+    void emitVtsAttributeDeclaration(Formatter& out) const;
+    void emitVtsMethodDeclaration(Formatter& out) const;
 
     bool hasOnewayMethods() const;
 
diff --git a/MemoryType.cpp b/MemoryType.cpp
index 81e22a4..444ba92 100644
--- a/MemoryType.cpp
+++ b/MemoryType.cpp
@@ -155,9 +155,8 @@
     *size = assertion.size();
 }
 
-status_t MemoryType::emitVtsTypeDeclarations(Formatter &out) const {
+void MemoryType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
-    return OK;
 }
 
 }  // namespace android
diff --git a/MemoryType.h b/MemoryType.h
index dd59b54..7bce55f 100644
--- a/MemoryType.h
+++ b/MemoryType.h
@@ -63,7 +63,7 @@
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 };
 
 }  // namespace android
diff --git a/PointerType.cpp b/PointerType.cpp
index 7233dea..cdf4a99 100644
--- a/PointerType.cpp
+++ b/PointerType.cpp
@@ -71,9 +71,8 @@
     return true;
 }
 
-status_t PointerType::emitVtsTypeDeclarations(Formatter &out) const {
+void PointerType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
-    return OK;
 }
 
 }  // namespace android
diff --git a/PointerType.h b/PointerType.h
index 58bc333..30c4a32 100644
--- a/PointerType.h
+++ b/PointerType.h
@@ -51,7 +51,7 @@
     bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const override;
     bool deepContainsPointer(std::unordered_set<const Type*>* visited) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 };
 
 }  // namespace android
diff --git a/ScalarType.cpp b/ScalarType.cpp
index 6078fff..2e2e7b2 100644
--- a/ScalarType.cpp
+++ b/ScalarType.cpp
@@ -277,10 +277,9 @@
         << ");\n";
 }
 
-status_t ScalarType::emitVtsTypeDeclarations(Formatter &out) const {
+void ScalarType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << "scalar_type: \"" << getVtsScalarType() << "\"\n";
-    return OK;
 }
 
 void ScalarType::getAlignmentAndSize(size_t *align, size_t *size) const {
diff --git a/ScalarType.h b/ScalarType.h
index fd12366..86305b8 100644
--- a/ScalarType.h
+++ b/ScalarType.h
@@ -96,7 +96,7 @@
             const std::string &offset,
             bool isReader) const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 
diff --git a/Scope.cpp b/Scope.cpp
index 0c7d8d6..751015f 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -145,79 +145,70 @@
     }
 }
 
-status_t Scope::forEachType(const std::function<status_t(Type *)> &func) const {
-    for (size_t i = 0; i < mTypes.size(); ++i) {
-        status_t err = func(mTypes[i]);
-
-        if (err != OK) {
-            return err;
-        }
-    }
-
-    return OK;
-}
-
-status_t Scope::emitTypeDeclarations(Formatter &out) const {
-    if (mTypes.empty()) return OK;
+void Scope::emitTypeDeclarations(Formatter& out) const {
+    if (mTypes.empty()) return;
 
     out << "// Forward declaration for forward reference support:\n";
-    forEachType([&](Type* type) {
+    for (const Type* type : mTypes) {
         type->emitTypeForwardDeclaration(out);
-        return OK;
-    });
+    }
     out << "\n";
 
     if (mTypeOrderChanged) {
         out << "// Order of inner types was changed for forward reference support.\n\n";
     }
-    return forEachType([&](Type* type) {
-        return type->emitTypeDeclarations(out);
-    });
+
+    for (const Type* type : mTypes) {
+        type->emitTypeDeclarations(out);
+    }
 }
 
 void Scope::emitGlobalTypeDeclarations(Formatter& out) const {
-    forEachType([&](Type* type) {
+    for (const Type* type : mTypes) {
         type->emitGlobalTypeDeclarations(out);
-        return OK;
-    });
+    }
 }
 
-status_t Scope::emitPackageTypeDeclarations(Formatter& out) const {
-    return forEachType([&](Type* type) { return type->emitPackageTypeDeclarations(out); });
+void Scope::emitPackageTypeDeclarations(Formatter& out) const {
+    for (const Type* type : mTypes) {
+        type->emitPackageTypeDeclarations(out);
+    }
 }
 
-status_t Scope::emitPackageHwDeclarations(Formatter& out) const {
-    return forEachType([&](Type* type) { return type->emitPackageHwDeclarations(out); });
+void Scope::emitPackageHwDeclarations(Formatter& out) const {
+    for (const Type* type : mTypes) {
+        type->emitPackageHwDeclarations(out);
+    }
 }
 
-status_t Scope::emitJavaTypeDeclarations(
-        Formatter &out, bool atTopLevel) const {
+void Scope::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
     if (mTypeOrderChanged) {
         out << "// Order of inner types was changed for forward reference support.\n\n";
     }
-    return forEachType([&](Type *type) {
-        return type->emitJavaTypeDeclarations(out, atTopLevel);
-    });
+
+    for (const Type* type : mTypes) {
+        type->emitJavaTypeDeclarations(out, atTopLevel);
+    }
 }
 
-status_t Scope::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
-    return forEachType([&](Type *type) {
-        return type->emitTypeDefinitions(out, prefix);
-    });
+void Scope::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
+    for (const Type* type : mTypes) {
+        type->emitTypeDefinitions(out, prefix);
+    }
 }
 
 const std::vector<NamedType *> &Scope::getSubTypes() const {
     return mTypes;
 }
 
-status_t Scope::emitVtsTypeDeclarations(Formatter &out) const {
-    return forEachType([&](Type *type) {
-        return type->emitVtsTypeDeclarations(out);
-    });
+void Scope::emitVtsTypeDeclarations(Formatter& out) const {
+    for (const Type* type : mTypes) {
+        type->emitVtsTypeDeclarations(out);
+    }
 }
 
 bool Scope::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
-    for (const auto &type : mTypes) {
+    for (const Type* type : mTypes) {
         if (!type->isJavaCompatible(visited)) {
             return false;
         }
@@ -227,10 +218,9 @@
 
 void Scope::appendToExportedTypesVector(
         std::vector<const Type *> *exportedTypes) const {
-    forEachType([&](Type *type) {
+    for (const Type* type : mTypes) {
         type->appendToExportedTypesVector(exportedTypes);
-        return OK;
-    });
+    }
 }
 
 ////////////////////////////////////////
diff --git a/Scope.h b/Scope.h
index e386a29..e8c9431 100644
--- a/Scope.h
+++ b/Scope.h
@@ -63,19 +63,18 @@
 
     void topologicalReorder(const std::unordered_map<const Type*, size_t>& reversedOrder);
 
-    status_t emitTypeDeclarations(Formatter &out) const override;
+    void emitTypeDeclarations(Formatter& out) const override;
     void emitGlobalTypeDeclarations(Formatter& out) const override;
-    status_t emitPackageTypeDeclarations(Formatter& out) const override;
-    status_t emitPackageHwDeclarations(Formatter& out) const override;
+    void emitPackageTypeDeclarations(Formatter& out) const override;
+    void emitPackageHwDeclarations(Formatter& out) const override;
 
-    status_t emitJavaTypeDeclarations(
-            Formatter &out, bool atTopLevel) const override;
+    void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const override;
 
-    status_t emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
+    void emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
 
     const std::vector<NamedType *> &getSubTypes() const;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 
     bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const override;
 
@@ -89,8 +88,6 @@
 
     bool mTypeOrderChanged = false;
 
-    status_t forEachType(const std::function<status_t(Type*)>& func) const;
-
     DISALLOW_COPY_AND_ASSIGN(Scope);
 };
 
diff --git a/StringType.cpp b/StringType.cpp
index 638ed31..a07086f 100644
--- a/StringType.cpp
+++ b/StringType.cpp
@@ -209,9 +209,8 @@
     return true;
 }
 
-status_t StringType::emitVtsTypeDeclarations(Formatter &out) const {
+void StringType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
-    return OK;
 }
 
 static HidlTypeAssertion assertion("hidl_string", 16 /* size */);
diff --git a/StringType.h b/StringType.h
index 6b3d811..a4e3691 100644
--- a/StringType.h
+++ b/StringType.h
@@ -77,7 +77,7 @@
     bool needsEmbeddedReadWrite() const override;
     bool resultNeedsDeref() const override;
 
-    status_t emitVtsTypeDeclarations(Formatter &out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 };
diff --git a/Type.cpp b/Type.cpp
index 8f4b50a..23bc745 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -616,29 +616,19 @@
     handleError(out, mode);
 }
 
-status_t Type::emitTypeDeclarations(Formatter &) const {
-    return OK;
-}
+void Type::emitTypeDeclarations(Formatter&) const {}
 
 void Type::emitTypeForwardDeclaration(Formatter&) const {}
 
 void Type::emitGlobalTypeDeclarations(Formatter&) const {}
 
-status_t Type::emitPackageTypeDeclarations(Formatter&) const {
-    return OK;
-}
+void Type::emitPackageTypeDeclarations(Formatter&) const {}
 
-status_t Type::emitPackageHwDeclarations(Formatter&) const {
-    return OK;
-}
+void Type::emitPackageHwDeclarations(Formatter&) const {}
 
-status_t Type::emitTypeDefinitions(Formatter&, const std::string&) const {
-    return OK;
-}
+void Type::emitTypeDefinitions(Formatter&, const std::string&) const {}
 
-status_t Type::emitJavaTypeDeclarations(Formatter &, bool) const {
-    return OK;
-}
+void Type::emitJavaTypeDeclarations(Formatter&, bool) const {}
 
 bool Type::needsEmbeddedReadWrite() const {
     return false;
@@ -701,12 +691,10 @@
     out << ");\n";
 }
 
-status_t Type::emitVtsTypeDeclarations(Formatter &) const {
-    return OK;
-}
+void Type::emitVtsTypeDeclarations(Formatter&) const {}
 
-status_t Type::emitVtsAttributeType(Formatter &out) const {
-    return emitVtsTypeDeclarations(out);
+void Type::emitVtsAttributeType(Formatter& out) const {
+    emitVtsTypeDeclarations(out);
 }
 
 bool Type::isJavaCompatible() const {
@@ -760,10 +748,7 @@
         std::vector<const Type *> * /* exportedTypes */) const {
 }
 
-status_t Type::emitExportedHeader(
-        Formatter & /* out */, bool /* forJava */) const {
-    return OK;
-}
+void Type::emitExportedHeader(Formatter& /* out */, bool /* forJava */) const {}
 
 bool Type::isNeverStrongReference() const {
     return false;
@@ -807,30 +792,22 @@
     return Type::validate();
 }
 
-status_t TemplatedType::emitVtsTypeDeclarations(Formatter &out) const {
+void TemplatedType::emitVtsTypeDeclarations(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << getVtsValueName() << ": {\n";
     out.indent();
-    status_t err = mElementType->emitVtsTypeDeclarations(out);
-    if (err != OK) {
-        return err;
-    }
+    mElementType->emitVtsTypeDeclarations(out);
     out.unindent();
     out << "}\n";
-    return OK;
 }
 
-status_t TemplatedType::emitVtsAttributeType(Formatter &out) const {
+void TemplatedType::emitVtsAttributeType(Formatter& out) const {
     out << "type: " << getVtsType() << "\n";
     out << getVtsValueName() << ": {\n";
     out.indent();
-    status_t status = mElementType->emitVtsAttributeType(out);
-    if (status != OK) {
-        return status;
-    }
+    mElementType->emitVtsAttributeType(out);
     out.unindent();
     out << "}\n";
-    return OK;
 }
 
 }  // namespace android
diff --git a/Type.h b/Type.h
index 364474f..db278d2 100644
--- a/Type.h
+++ b/Type.h
@@ -254,7 +254,7 @@
             const std::string &offset,
             bool isReader) const;
 
-    virtual status_t emitTypeDeclarations(Formatter &out) const;
+    virtual void emitTypeDeclarations(Formatter& out) const;
 
     virtual void emitGlobalTypeDeclarations(Formatter& out) const;
 
@@ -267,18 +267,17 @@
     // at global scope, i.e. enum class operators.
     // For android.hardware.foo@1.0::*, this will be in namespace
     // android::hardware::foo::V1_0
-    virtual status_t emitPackageTypeDeclarations(Formatter& out) const;
+    virtual void emitPackageTypeDeclarations(Formatter& out) const;
 
     // Emit any declarations pertaining to this type that have to be
     // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel
     // For android.hardware.foo@1.0::*, this will be in namespace
     // android::hardware::foo::V1_0
-    virtual status_t emitPackageHwDeclarations(Formatter& out) const;
+    virtual void emitPackageHwDeclarations(Formatter& out) const;
 
-    virtual status_t emitTypeDefinitions(Formatter& out, const std::string& prefix) const;
+    virtual void emitTypeDefinitions(Formatter& out, const std::string& prefix) const;
 
-    virtual status_t emitJavaTypeDeclarations(
-            Formatter &out, bool atTopLevel) const;
+    virtual void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const;
 
     virtual bool needsEmbeddedReadWrite() const;
     virtual bool resultNeedsDeref() const;
@@ -289,10 +288,10 @@
 
     // Generates type declaration for vts proto file.
     // TODO (b/30844146): make it a pure virtual method.
-    virtual status_t emitVtsTypeDeclarations(Formatter &out) const;
+    virtual void emitVtsTypeDeclarations(Formatter& out) const;
     // Generates type declaration as attribute of method (return value or method
     // argument) or attribute of compound type for vts proto file.
-    virtual status_t emitVtsAttributeType(Formatter &out) const;
+    virtual void emitVtsAttributeType(Formatter& out) const;
 
     // Returns true iff this type is supported through the Java backend.
     bool isJavaCompatible() const;
@@ -309,7 +308,7 @@
     virtual void appendToExportedTypesVector(
             std::vector<const Type *> *exportedTypes) const;
 
-    virtual status_t emitExportedHeader(Formatter &out, bool forJava) const;
+    virtual void emitExportedHeader(Formatter& out, bool forJava) const;
 
     virtual bool isNeverStrongReference() const;
 
@@ -367,8 +366,8 @@
 
     virtual status_t validate() const override;
 
-    status_t emitVtsTypeDeclarations(Formatter& out) const override;
-    status_t emitVtsAttributeType(Formatter& out) const override;
+    void emitVtsTypeDeclarations(Formatter& out) const override;
+    void emitVtsAttributeType(Formatter& out) const override;
 
    protected:
     TemplatedType(Scope* parent);
diff --git a/TypeDef.cpp b/TypeDef.cpp
index d0e0c09..dcefc57 100644
--- a/TypeDef.cpp
+++ b/TypeDef.cpp
@@ -73,14 +73,12 @@
     return false;
 }
 
-status_t TypeDef::emitTypeDeclarations(Formatter &out) const {
+void TypeDef::emitTypeDeclarations(Formatter& out) const {
     out << "typedef "
         << mReferencedType->getCppStackType()
         << " "
         << localName()
         << ";\n\n";
-
-    return OK;
 }
 
 }  // namespace android
diff --git a/TypeDef.h b/TypeDef.h
index d383f50..5ebba3e 100644
--- a/TypeDef.h
+++ b/TypeDef.h
@@ -43,7 +43,7 @@
 
     std::vector<const Reference<Type>*> getReferences() const override;
 
-    status_t emitTypeDeclarations(Formatter &out) const override;
+    void emitTypeDeclarations(Formatter& out) const override;
 
    private:
     Reference<Type> mReferencedType;
diff --git a/generateCpp.cpp b/generateCpp.cpp
index d4606b7..66f6c87 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -204,7 +204,7 @@
     }).endl().endl();
 }
 
-status_t AST::generateInterfaceHeader(Formatter& out) const {
+void AST::generateInterfaceHeader(Formatter& out) const {
     const Interface *iface = getInterface();
     std::string ifaceName = iface ? iface->localName() : "types";
     const std::string guard = makeHeaderGuard(ifaceName);
@@ -261,11 +261,7 @@
         generateCppTag(out, "android::hardware::details::i_tag");
     }
 
-    status_t err = emitTypeDeclarations(out);
-
-    if (err != OK) {
-        return err;
-    }
+    emitTypeDeclarations(out);
 
     if (iface) {
         out << "virtual bool isRemote() const ";
@@ -340,11 +336,7 @@
         out << "};\n\n";
     }
 
-    err = mRootScope.emitPackageTypeDeclarations(out);
-
-    if (err != OK) {
-        return err;
-    }
+    mRootScope.emitPackageTypeDeclarations(out);
 
     out << "\n";
     enterLeaveNamespace(out, false /* enter */);
@@ -352,11 +344,9 @@
     mRootScope.emitGlobalTypeDeclarations(out);
 
     out << "\n#endif  // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::generateHwBinderHeader(Formatter& out) const {
+void AST::generateHwBinderHeader(Formatter& out) const {
     const Interface *iface = getInterface();
     std::string klassName = iface ? iface->getHwName() : "hwtypes";
 
@@ -388,19 +378,14 @@
 
     enterLeaveNamespace(out, true /* enter */);
 
-    status_t err = mRootScope.emitPackageHwDeclarations(out);
-    if (err != OK) {
-        return err;
-    }
+    mRootScope.emitPackageHwDeclarations(out);
 
     enterLeaveNamespace(out, false /* enter */);
 
     out << "\n#endif  // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::emitTypeDeclarations(Formatter &out) const {
+void AST::emitTypeDeclarations(Formatter& out) const {
     return mRootScope.emitTypeDeclarations(out);
 }
 
@@ -431,8 +416,7 @@
     }).endl().endl();
 }
 
-status_t AST::generatePassthroughMethod(Formatter &out,
-                                        const Method *method) const {
+void AST::generatePassthroughMethod(Formatter& out, const Method* method) const {
     method->generateCppSignature(out);
 
     out << " {\n";
@@ -443,7 +427,7 @@
         method->cppImpl(IMPL_PASSTHROUGH, out);
         out.unindent();
         out << "}\n\n";
-        return OK;
+        return;
     }
 
     const bool returnsValue = !method->results().empty();
@@ -557,13 +541,9 @@
 
     out.unindent();
     out << "}\n";
-
-    return OK;
 }
 
-status_t AST::generateMethods(Formatter& out,
-                              const MethodGenerator& gen,
-                              bool includeParent) const {
+void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
     const Interface* iface = mRootScope.getInterface();
 
     const Interface *prevIterface = nullptr;
@@ -584,16 +564,10 @@
                 << " follow.\n";
             prevIterface = superInterface;
         }
-        status_t err = gen(method, superInterface);
-
-        if (err != OK) {
-            return err;
-        }
+        gen(method, superInterface);
     }
 
     out << "\n";
-
-    return OK;
 }
 
 void AST::generateTemplatizationLink(Formatter& out) const {
@@ -604,7 +578,7 @@
     out << "typedef " << tag << " _hidl_tag;\n\n";
 }
 
-status_t AST::generateStubHeader(Formatter& out) const {
+void AST::generateStubHeader(Formatter& out) const {
     CHECK(AST::isInterface());
 
     const Interface* iface = mRootScope.getInterface();
@@ -661,35 +635,33 @@
 
     out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
-        if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
-            return OK;
-        }
+    generateMethods(out,
+                    [&](const Method* method, const Interface*) {
+                        if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
+                            return;
+                        }
 
-        out << "static ::android::status_t _hidl_" << method->name() << "(\n";
+                        out << "static ::android::status_t _hidl_" << method->name() << "(\n";
 
-        out.indent(2, [&] {
-            out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
-                << "const ::android::hardware::Parcel &_hidl_data,\n"
-                << "::android::hardware::Parcel *_hidl_reply,\n"
-                << "TransactCallback _hidl_cb);\n";
-        }).endl().endl();
-
-        return OK;
-    }, false /* include parents */);
-
-    if (err != OK) {
-        return err;
-    }
+                        out.indent(2,
+                                   [&] {
+                                       out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
+                                           << "const ::android::hardware::Parcel &_hidl_data,\n"
+                                           << "::android::hardware::Parcel *_hidl_reply,\n"
+                                           << "TransactCallback _hidl_cb);\n";
+                                   })
+                            .endl()
+                            .endl();
+                    },
+                    false /* include parents */);
 
     out.unindent();
     out << "private:\n";
     out.indent();
 
-
-    err = generateMethods(out, [&](const Method *method, const Interface *iface) {
+    generateMethods(out, [&](const Method* method, const Interface* iface) {
         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
-            return OK;
+            return;
         }
         const bool returnsValue = !method->results().empty();
         const NamedReference<Type>* elidedReturn = method->canElideCallback();
@@ -701,11 +673,7 @@
         }
         method->generateCppSignature(out);
         out << ";\n";
-        return OK;
     });
-    if (err != OK) {
-        return err;
-    }
 
     out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
     out.unindent();
@@ -714,14 +682,12 @@
     enterLeaveNamespace(out, false /* enter */);
 
     out << "\n#endif  // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::generateProxyHeader(Formatter& out) const {
+void AST::generateProxyHeader(Formatter& out) const {
     if (!AST::isInterface()) {
         // types.hal does not get a proxy header.
-        return OK;
+        return;
     }
 
     const Interface* iface = mRootScope.getInterface();
@@ -761,41 +727,32 @@
 
     out << "virtual bool isRemote() const override { return true; }\n\n";
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
-        if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
-            return OK;
-        }
+    generateMethods(
+        out,
+        [&](const Method* method, const Interface*) {
+            if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
+                return;
+            }
 
-        out << "static ";
-        method->generateCppReturnType(out);
-        out << " _hidl_"
-            << method->name()
-            << "("
-            << "::android::hardware::IInterface* _hidl_this, "
-            << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
+            out << "static ";
+            method->generateCppReturnType(out);
+            out << " _hidl_" << method->name() << "("
+                << "::android::hardware::IInterface* _hidl_this, "
+                << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
 
-        if (!method->hasEmptyCppArgSignature()) {
-            out << ", ";
-        }
-        method->emitCppArgSignature(out);
-        out << ");\n";
-        return OK;
-    }, false /* include parents */);
+            if (!method->hasEmptyCppArgSignature()) {
+                out << ", ";
+            }
+            method->emitCppArgSignature(out);
+            out << ");\n";
+        },
+        false /* include parents */);
 
-    if (err != OK) {
-        return err;
-    }
-
-    err = generateMethods(out, [&](const Method *method, const Interface *) {
+    generateMethods(out, [&](const Method* method, const Interface*) {
         method->generateCppSignature(out);
         out << " override;\n";
-        return OK;
     });
 
-    if (err != OK) {
-        return err;
-    }
-
     out.unindent();
     out << "private:\n";
     out.indent();
@@ -808,11 +765,9 @@
     enterLeaveNamespace(out, false /* enter */);
 
     out << "\n#endif  // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::generateCppSource(Formatter& out) const {
+void AST::generateCppSource(Formatter& out) const {
     std::string baseName = getBaseName();
     const Interface *iface = getInterface();
 
@@ -853,9 +808,9 @@
     enterLeaveNamespace(out, true /* enter */);
     out << "\n";
 
-    status_t err = generateTypeSource(out, iface ? iface->localName() : "");
+    generateTypeSource(out, iface ? iface->localName() : "");
 
-    if (err == OK && iface) {
+    if (iface) {
         const Interface* iface = mRootScope.getInterface();
 
         // need to be put here, generateStubSource is using this.
@@ -911,23 +866,10 @@
         });
         out << "};\n\n";
 
-        err = generateInterfaceSource(out);
-    }
-
-    if (err == OK && iface) {
-        err = generateProxySource(out, iface->fqName());
-    }
-
-    if (err == OK && iface) {
-        err = generateStubSource(out, iface);
-    }
-
-    if (err == OK && iface) {
-        err = generatePassthroughSource(out);
-    }
-
-    if (err == OK && iface) {
-        const Interface* iface = mRootScope.getInterface();
+        generateInterfaceSource(out);
+        generateProxySource(out, iface->fqName());
+        generateStubSource(out, iface);
+        generatePassthroughSource(out);
 
         if (isIBase()) {
             out << "// skipped getService, registerAsService, registerForNotifications\n";
@@ -943,8 +885,6 @@
     out << "\n";
 
     enterLeaveNamespace(out, false /* enter */);
-
-    return err;
 }
 
 void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
@@ -957,9 +897,8 @@
     }).endl().endl();
 }
 
-status_t AST::generateTypeSource(
-        Formatter &out, const std::string &ifaceName) const {
-    return mRootScope.emitTypeDefinitions(out, ifaceName);
+void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
+    mRootScope.emitTypeDefinitions(out, ifaceName);
 }
 
 void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
@@ -1011,10 +950,8 @@
     }
 }
 
-status_t AST::generateProxyMethodSource(Formatter &out,
-                                        const std::string &klassName,
-                                        const Method *method,
-                                        const Interface *superInterface) const {
+void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
+                                    const Method* method, const Interface* superInterface) const {
     method->generateCppSignature(out,
                                  klassName,
                                  true /* specify namespaces */);
@@ -1023,11 +960,9 @@
         out.block([&] {
             method->cppImpl(IMPL_PROXY, out);
         }).endl().endl();
-        return OK;
+        return;
     }
 
-    status_t err = OK;
-
     out.block([&] {
         const bool returnsValue = !method->results().empty();
         const NamedReference<Type>* elidedReturn = method->canElideCallback();
@@ -1061,15 +996,12 @@
 
         out << "return _hidl_out;\n";
     }).endl().endl();
-
-    return err;
 }
 
-status_t AST::generateStaticProxyMethodSource(Formatter &out,
-                                              const std::string &klassName,
-                                              const Method *method) const {
+void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
+                                          const Method* method) const {
     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
-        return OK;
+        return;
     }
 
     method->generateCppReturnType(out);
@@ -1239,11 +1171,9 @@
 
     out.unindent();
     out << "}\n\n";
-    return OK;
 }
 
-status_t AST::generateProxySource(
-        Formatter &out, const FQName &fqName) const {
+void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
     const std::string klassName = fqName.getInterfaceProxyName();
 
     out << klassName
@@ -1268,24 +1198,18 @@
     out.unindent();
     out << "}\n\n";
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
-        return generateStaticProxyMethodSource(out, klassName, method);
-    }, false /* include parents */);
+    generateMethods(out,
+                    [&](const Method* method, const Interface*) {
+                        generateStaticProxyMethodSource(out, klassName, method);
+                    },
+                    false /* include parents */);
 
-    if (err != OK) {
-        return err;
-    }
-
-    err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
-        return generateProxyMethodSource(out, klassName, method, superInterface);
+    generateMethods(out, [&](const Method* method, const Interface* superInterface) {
+        generateProxyMethodSource(out, klassName, method, superInterface);
     });
-
-    return err;
 }
 
-status_t AST::generateStubSource(
-        Formatter &out,
-        const Interface *iface) const {
+void AST::generateStubSource(Formatter& out, const Interface* iface) const {
     const std::string interfaceName = iface->localName();
     const std::string klassName = iface->getStubName();
 
@@ -1350,24 +1274,22 @@
         out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
     }).endl().endl();
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
-        return generateStaticStubMethodSource(out, iface->fqName(), method);
-    }, false /* include parents */);
+    generateMethods(out,
+                    [&](const Method* method, const Interface*) {
+                        return generateStaticStubMethodSource(out, iface->fqName(), method);
+                    },
+                    false /* include parents */);
 
-    err = generateMethods(out, [&](const Method *method, const Interface *) {
+    generateMethods(out, [&](const Method* method, const Interface*) {
         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
-            return OK;
+            return;
         }
         method->generateCppSignature(out, iface->getStubName());
         out << " ";
         out.block([&] {
             method->cppImpl(IMPL_STUB_IMPL, out);
         }).endl();
-        return OK;
     });
-    if (err != OK) {
-        return err;
-    }
 
     out << "::android::status_t " << klassName << "::onTransact(\n";
 
@@ -1405,11 +1327,7 @@
         out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
         out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
 
-        status_t err = generateStubSourceForMethod(out, method, superInterface);
-
-        if (err != OK) {
-            return err;
-        }
+        generateStubSourceForMethod(out, method, superInterface);
 
         out.unindent();
         out << "}\n\n";
@@ -1454,19 +1372,14 @@
 
     out.unindent();
     out << "}\n\n";
-
-    return OK;
 }
 
-status_t AST::generateStubSourceForMethod(
-        Formatter &out,
-        const Method *method,
-        const Interface* superInterface) const {
-
+void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
+                                      const Interface* superInterface) const {
     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
         method->cppImpl(IMPL_STUB, out);
         out << "break;\n";
-        return OK;
+        return;
     }
 
     out << "_hidl_err = "
@@ -1477,15 +1390,12 @@
         << method->name()
         << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
     out << "break;\n";
-
-    return OK;
 }
 
-status_t AST::generateStaticStubMethodSource(Formatter &out,
-                                             const FQName &fqName,
-                                             const Method *method) const {
+void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
+                                         const Method* method) const {
     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
-        return OK;
+        return;
     }
 
     const std::string& klassName = fqName.getInterfaceStubName();
@@ -1703,14 +1613,12 @@
     out << "return _hidl_err;\n";
     out.unindent();
     out << "}\n\n";
-
-    return OK;
 }
 
-status_t AST::generatePassthroughHeader(Formatter& out) const {
+void AST::generatePassthroughHeader(Formatter& out) const {
     if (!AST::isInterface()) {
         // types.hal does not get a stub header.
-        return OK;
+        return;
     }
 
     const Interface* iface = mRootScope.getInterface();
@@ -1760,14 +1668,10 @@
     generateTemplatizationLink(out);
     generateCppTag(out, "android::hardware::details::bs_tag");
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
-        return generatePassthroughMethod(out, method);
+    generateMethods(out, [&](const Method* method, const Interface*) {
+        generatePassthroughMethod(out, method);
     });
 
-    if (err != OK) {
-        return err;
-    }
-
     out.unindent();
     out << "private:\n";
     out.indent();
@@ -1789,17 +1693,15 @@
     enterLeaveNamespace(out, false /* enter */);
 
     out << "\n#endif  // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::generateInterfaceSource(Formatter &out) const {
+void AST::generateInterfaceSource(Formatter& out) const {
     const Interface* iface = mRootScope.getInterface();
 
     // generate castFrom functions
     std::string childTypeResult = iface->getCppResultType();
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+    generateMethods(out, [&](const Method* method, const Interface*) {
         bool reserved = method->isHidlReserved();
 
         if (!reserved) {
@@ -1814,11 +1716,8 @@
 
         out << "\n";
 
-        return OK;
+        return;
     });
-    if (err != OK) {
-        return err;
-    }
 
     for (const Interface *superType : iface->typeChain()) {
         out << "// static \n::android::hardware::Return<"
@@ -1850,11 +1749,9 @@
         out.unindent();
         out << "}\n\n";
     }
-
-    return OK;
 }
 
-status_t AST::generatePassthroughSource(Formatter &out) const {
+void AST::generatePassthroughSource(Formatter& out) const {
     const Interface* iface = mRootScope.getInterface();
 
     const std::string klassName = iface->getPassthroughName();
@@ -1901,8 +1798,6 @@
 
 
     }
-
-    return OK;
 }
 
 void AST::generateCppAtraceCall(Formatter &out,
diff --git a/generateCppAdapter.cpp b/generateCppAdapter.cpp
index 70e3816..1fbfb57 100644
--- a/generateCppAdapter.cpp
+++ b/generateCppAdapter.cpp
@@ -34,7 +34,7 @@
 
 namespace android {
 
-status_t AST::generateCppAdapterHeader(Formatter& out) const {
+void AST::generateCppAdapterHeader(Formatter& out) const {
     const std::string klassName = AST::isInterface() ? getInterface()->getAdapterName() : "Atypes";
     const std::string guard = makeHeaderGuard(klassName, true /* indicateGenerated */);
 
@@ -58,14 +58,12 @@
 
             generateMethods(out, [&](const Method* method, const Interface* /* interface */) {
                 if (method->isHidlReserved()) {
-                    return OK;
+                    return;
                 }
 
                 out << "virtual ";
                 method->generateCppSignature(out);
                 out << " override;\n";
-
-                return OK;
             });
             out << "private:\n";
             out << "::android::sp<" << mockName << "> mImpl;\n";
@@ -78,11 +76,9 @@
     }
 
     out << "#endif // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::generateCppAdapterSource(Formatter& out) const {
+void AST::generateCppAdapterSource(Formatter& out) const {
     const std::string klassName = AST::isInterface() ? getInterface()->getAdapterName() : "Atypes";
 
     generateCppPackageInclude(out, mPackage, klassName);
@@ -112,7 +108,6 @@
 
         generateMethods(out, [&](const Method* method, const Interface* /* interface */) {
             generateAdapterMethod(out, method);
-            return OK;
         });
 
         enterLeaveNamespace(out, false /* enter */);
@@ -120,8 +115,6 @@
     } else {
         out << "// no adapters for types.hal\n";
     }
-
-    return OK;
 }
 
 void AST::generateAdapterMethod(Formatter& out, const Method* method) const {
diff --git a/generateCppImpl.cpp b/generateCppImpl.cpp
index 74a4649..18fac6b 100644
--- a/generateCppImpl.cpp
+++ b/generateCppImpl.cpp
@@ -37,13 +37,11 @@
     out << "HIDL_FETCH_" << ifaceName;
 }
 
-status_t AST::generateStubImplMethod(Formatter &out,
-                                     const std::string &className,
-                                     const Method *method) const {
-
+void AST::generateStubImplMethod(Formatter& out, const std::string& className,
+                                 const Method* method) const {
     // ignore HIDL reserved methods -- implemented in IFoo already.
     if (method->isHidlReserved()) {
-        return OK;
+        return;
     }
 
     method->generateCppSignature(out, className, false /* specifyNamespaces */);
@@ -67,13 +65,13 @@
 
     out << "}\n\n";
 
-    return OK;
+    return;
 }
 
-status_t AST::generateCppImplHeader(Formatter& out) const {
+void AST::generateCppImplHeader(Formatter& out) const {
     if (!AST::isInterface()) {
         // types.hal does not get a stub header.
-        return OK;
+        return;
     }
 
     const Interface* iface = mRootScope.getInterface();
@@ -110,21 +108,16 @@
 
     out.indent();
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
+    generateMethods(out, [&](const Method* method, const Interface*) {
         // ignore HIDL reserved methods -- implemented in IFoo already.
         if (method->isHidlReserved()) {
-            return OK;
+            return;
         }
         method->generateCppSignature(out, "" /* className */,
                 false /* specifyNamespaces */);
         out << " override;\n";
-        return OK;
     });
 
-    if (err != OK) {
-        return err;
-    }
-
     out.unindent();
 
     out << "};\n\n";
@@ -140,14 +133,12 @@
     enterLeaveNamespace(out, false /* leave */);
 
     out << "\n#endif  // " << guard << "\n";
-
-    return OK;
 }
 
-status_t AST::generateCppImplSource(Formatter& out) const {
+void AST::generateCppImplSource(Formatter& out) const {
     if (!AST::isInterface()) {
         // types.hal does not get a stub header.
-        return OK;
+        return;
     }
 
     const Interface* iface = mRootScope.getInterface();
@@ -158,14 +149,10 @@
     enterLeaveNamespace(out, true /* enter */);
     out << "namespace implementation {\n\n";
 
-    status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
-        return generateStubImplMethod(out, baseName, method);
+    generateMethods(out, [&](const Method* method, const Interface*) {
+        generateStubImplMethod(out, baseName, method);
     });
 
-    if (err != OK) {
-        return err;
-    }
-
     out.setLinePrefix("//");
     out << iface->localName()
         << "* ";
@@ -179,8 +166,6 @@
 
     out << "}  // namespace implementation\n";
     enterLeaveNamespace(out, false /* leave */);
-
-    return OK;
 }
 
 }  // namespace android
diff --git a/generateJava.cpp b/generateJava.cpp
index c5b3844..973af72 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -43,7 +43,7 @@
             isReader);
 }
 
-status_t AST::generateJavaTypes(Formatter& out, const std::string& limitToType) const {
+void AST::generateJavaTypes(Formatter& out, const std::string& limitToType) const {
     // Splits types.hal up into one java file per declared type.
     CHECK(!limitToType.empty()) << getFilename();
 
@@ -59,11 +59,11 @@
 
         out << "package " << mPackage.javaPackage() << ";\n\n\n";
 
-        return type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
+        type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
+        return;
     }
 
     CHECK(false) << "generateJavaTypes could not find limitToType type";
-    return UNKNOWN_ERROR;
 }
 
 void emitGetService(
@@ -106,19 +106,12 @@
     }).endl().endl();
 }
 
-status_t AST::generateJava(Formatter& out, const std::string& limitToType) const {
-    if (!isJavaCompatible()) {
-        fprintf(stderr,
-                "ERROR: This interface is not Java compatible. The Java backend"
-                " does NOT support union types nor native handles. "
-                "In addition, vectors of arrays are limited to at most "
-                "one-dimensional arrays and vectors of {vectors,interfaces} are"
-                " not supported.\n");
-        return UNKNOWN_ERROR;
-    }
+void AST::generateJava(Formatter& out, const std::string& limitToType) const {
+    CHECK(isJavaCompatible()) << getFilename();
 
     if (!AST::isInterface()) {
-        return generateJavaTypes(out, limitToType);
+        generateJavaTypes(out, limitToType);
+        return;
     }
 
     const Interface* iface = mRootScope.getInterface();
@@ -220,11 +213,7 @@
     emitGetService(out, ifaceName, iface->fqName().string(), true /* isRetry */);
     emitGetService(out, ifaceName, iface->fqName().string(), false /* isRetry */);
 
-    status_t err = emitJavaTypeDeclarations(out);
-
-    if (err != OK) {
-        return err;
-    }
+    emitJavaTypeDeclarations(out);
 
     for (const auto &method : iface->methods()) {
         if (method->isHiddenFromJava()) {
@@ -669,12 +658,10 @@
 
     out.unindent();
     out << "}\n";
-
-    return OK;
 }
 
-status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
-    return mRootScope.emitJavaTypeDeclarations(out, false /* atTopLevel */);
+void AST::emitJavaTypeDeclarations(Formatter& out) const {
+    mRootScope.emitJavaTypeDeclarations(out, false /* atTopLevel */);
 }
 
 }  // namespace android
diff --git a/generateVts.cpp b/generateVts.cpp
index d0a1d6d..8a37ae3 100644
--- a/generateVts.cpp
+++ b/generateVts.cpp
@@ -29,7 +29,7 @@
 
 namespace android {
 
-status_t AST::emitVtsTypeDeclarations(Formatter &out) const {
+void AST::emitVtsTypeDeclarations(Formatter& out) const {
     if (AST::isInterface()) {
         const Interface* iface = mRootScope.getInterface();
         return iface->emitVtsAttributeDeclaration(out);
@@ -42,18 +42,13 @@
         }
         out << "attribute: {\n";
         out.indent();
-        status_t status = type->emitVtsTypeDeclarations(out);
-        if (status != OK) {
-            return status;
-        }
+        type->emitVtsTypeDeclarations(out);
         out.unindent();
         out << "}\n\n";
     }
-
-    return OK;
 }
 
-status_t AST::generateVts(Formatter& out) const {
+void AST::generateVts(Formatter& out) const {
     std::string baseName = AST::getBaseName();
     const Interface *iface = AST::getInterface();
 
@@ -86,28 +81,19 @@
         std::vector<const Interface *> chain = iface->typeChain();
 
         // Generate all the attribute declarations first.
-        status_t status = emitVtsTypeDeclarations(out);
-        if (status != OK) {
-            return status;
-        }
+        emitVtsTypeDeclarations(out);
+
         // Generate all the method declarations.
         for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
             const Interface *superInterface = *it;
-            status_t status = superInterface->emitVtsMethodDeclaration(out);
-            if (status != OK) {
-                return status;
-            }
+            superInterface->emitVtsMethodDeclaration(out);
         }
 
         out.unindent();
         out << "}\n";
     } else {
-        status_t status = emitVtsTypeDeclarations(out);
-        if (status != OK) {
-            return status;
-        }
+        emitVtsTypeDeclarations(out);
     }
-    return OK;
 }
 
 }  // namespace android
diff --git a/main.cpp b/main.cpp
index 3d10854..dce69b1 100644
--- a/main.cpp
+++ b/main.cpp
@@ -110,8 +110,8 @@
 
 // Represents a -L option, takes a fqName and generates files
 struct OutputHandler {
-    using ValidationFunction =
-        std::function<bool(const FQName& fqName, const std::string& language)>;
+    using ValidationFunction = std::function<bool(
+        const FQName& fqName, const Coordinator* coordinator, const std::string& language)>;
 
     std::string mKey;                 // -L in Android.bp
     std::string mDescription;         // for display in help menu
@@ -125,8 +125,9 @@
     const std::string& description() const { return mDescription; }
 
     status_t generate(const FQName& fqName, const Coordinator* coordinator) const;
-    status_t validate(const FQName& fqName, const std::string& language) const {
-        return mValidate(fqName, language);
+    status_t validate(const FQName& fqName, const Coordinator* coordinator,
+                      const std::string& language) const {
+        return mValidate(fqName, coordinator, language);
     }
 
     status_t writeDepFile(const FQName& fqName, const Coordinator* coordinator) const;
@@ -247,7 +248,7 @@
 }
 
 // Use an AST function as a OutputHandler GenerationFunction
-static FileGenerator::GenerationFunction astGenerationFunction(status_t (AST::*generate)(Formatter&)
+static FileGenerator::GenerationFunction astGenerationFunction(void (AST::*generate)(Formatter&)
                                                                    const = nullptr) {
     return [generate](Formatter& out, const FQName& fqName,
                       const Coordinator* coordinator) -> status_t {
@@ -258,7 +259,9 @@
         }
 
         if (generate == nullptr) return OK;  // just parsing AST
-        return (ast->*generate)(out);
+        (ast->*generate)(out);
+
+        return OK;
     };
 }
 
@@ -289,7 +292,8 @@
         fprintf(stderr, "ERROR: Could not parse %s. Aborting.\n", fqName.string().c_str());
         return UNKNOWN_ERROR;
     }
-    return ast->generateJava(out, limitToType);
+    ast->generateJava(out, limitToType);
+    return OK;
 };
 
 static status_t dumpDefinedButUnreferencedTypeNames(const FQName& packageFQName,
@@ -414,8 +418,8 @@
     return false;
 }
 
-bool validateIsPackage(
-        const FQName &fqName, const std::string & /* language */) {
+bool validateIsPackage(const FQName& fqName, const Coordinator*,
+                       const std::string& /* language */) {
     if (fqName.package().empty()) {
         fprintf(stderr, "ERROR: Expecting package name\n");
         return false;
@@ -708,8 +712,8 @@
     return OK;
 }
 
-bool validateForSource(
-        const FQName &fqName, const std::string &language) {
+bool validateForSource(const FQName& fqName, const Coordinator* coordinator,
+                       const std::string& language) {
     if (fqName.package().empty()) {
         fprintf(stderr, "ERROR: Expecting package name\n");
         return false;
@@ -739,6 +743,23 @@
         return true;
     }
 
+    if (language == "java") {
+        bool isJavaCompatible;
+        status_t err = isPackageJavaCompatible(fqName, coordinator, &isJavaCompatible);
+        if (err != OK) return false;
+
+        if (!isJavaCompatible) {
+            fprintf(stderr,
+                    "ERROR: %s is not Java compatible. The Java backend"
+                    " does NOT support union types nor native handles. "
+                    "In addition, vectors of arrays are limited to at most "
+                    "one-dimensional arrays and vectors of {vectors,interfaces} are"
+                    " not supported.\n",
+                    fqName.string().c_str());
+            return false;
+        }
+    }
+
     return true;
 }
 
@@ -1090,7 +1111,7 @@
         OutputMode::NEEDS_SRC,
         Coordinator::Location::PACKAGE_ROOT,
         GenerationGranularity::PER_PACKAGE,
-        [](const FQName &, const std::string &) {
+        [](const FQName &, const Coordinator*, const std::string &) {
            fprintf(stderr, "ERROR: makefile output is not supported. Use -Landroidbp for all build file generation.\n");
            return false;
         },
@@ -1341,7 +1362,7 @@
             if (err != OK) return err;
         }
 
-        if (!outputFormat->validate(fqName, outputFormat->name())) {
+        if (!outputFormat->validate(fqName, &coordinator, outputFormat->name())) {
             fprintf(stderr,
                     "ERROR: output handler failed.\n");
             exit(1);