[fidlc] Properly report unknown protocols

Change-Id: I5dc139642fbe341053b92b9b2c9e8b710235ec3b
diff --git a/zircon/system/host/fidl/lib/flat_ast.cpp b/zircon/system/host/fidl/lib/flat_ast.cpp
index 9a16df4..481dd7a 100644
--- a/zircon/system/host/fidl/lib/flat_ast.cpp
+++ b/zircon/system/host/fidl/lib/flat_ast.cpp
@@ -2357,9 +2357,8 @@
     case Decl::Kind::kInterface: {
         auto interface_decl = static_cast<const Interface*>(decl);
         for (const auto& superinterface : interface_decl->superinterfaces) {
-            auto type_decl = LookupDeclByName(superinterface);
-            assert(type_decl);
-            edges.insert(type_decl);
+            if (auto type_decl = LookupDeclByName(superinterface); type_decl)
+                edges.insert(type_decl);
         }
         for (const auto& method : interface_decl->methods) {
             if (method.maybe_request != nullptr) {
@@ -2825,8 +2824,14 @@
     auto CheckScopes = [this, &interface_declaration, &method_scope](const Interface* interface, auto Visitor) -> bool {
         for (const auto& name : interface->superinterfaces) {
             auto decl = LookupDeclByName(name);
-            if (decl == nullptr)
-                return Fail(name, "There is no declaration with this name");
+            // TODO(FIDL-603): Special handling here should not be required, we
+            // should first rely on creating the types representing composed
+            // protocols.
+            if (!decl) {
+                std::string message("unknown type ");
+                message.append(name.name_part());
+                return Fail(name, message);
+            }
             if (decl->kind != Decl::Kind::kInterface)
                 return Fail(name, "This superinterface declaration is not an interface");
             if (!decl->HasAttribute("FragileBase")) {
diff --git a/zircon/system/utest/fidl-compiler/protocol_tests.cpp b/zircon/system/utest/fidl-compiler/protocol_tests.cpp
index 162ffcd..802c79d 100644
--- a/zircon/system/utest/fidl-compiler/protocol_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/protocol_tests.cpp
@@ -200,6 +200,25 @@
     END_TEST;
 }
 
+bool invalid_cannot_compose_missing_protocol() {
+    BEGIN_TEST;
+
+    TestLibrary library(R"FIDL(
+library example;
+
+protocol Child {
+    compose MissingParent;
+};
+
+)FIDL");
+    ASSERT_FALSE(library.Compile());
+    auto errors = library.errors();
+    ASSERT_EQ(errors.size(), 1);
+    ASSERT_STR_STR(errors[0].c_str(), "unknown type MissingParent");
+
+    END_TEST;
+}
+
 bool invalid_cannot_use_ordinals_in_protocol_declaration() {
     BEGIN_TEST;
 
@@ -368,6 +387,7 @@
 RUN_TEST(invalid_cannot_attach_attributes_to_compose)
 RUN_TEST(invalid_cannot_compose_yourself)
 RUN_TEST(invalid_cannot_compose_twice_the_same_protocol)
+RUN_TEST(invalid_cannot_compose_missing_protocol)
 RUN_TEST(invalid_cannot_use_ordinals_in_protocol_declaration)
 RUN_TEST(invalid_no_other_pragma_than_compose)
 RUN_TEST(invalid_composed_protocols_have_clashing_names)