Check missing uncoditionally loaded missing modules at runtime

A potentially inherited (via dynamically calculated path) module may in turn
unconditionally load a module that does no exist in a source tree -- it is
not an error if this potentially inherited module is actually never inherited
because its dynamically calculated path will never reference it. Instead of
emitting an uncoditional `load` for a non-existent file (which is going to fail
in the Starlark parser), emit conditional load and a runtime check.

Fixes: 213922819
Test: internal
Change-Id: I92177878e199a1f00e5f0c4045c0c0daeddd6bdb
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 04038e4..df6b725 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -249,19 +249,19 @@
 	gctx.writef("load(%q, %q)", baseUri, baseName)
 	// Emit exactly one load statement for each URI.
 	loadedSubConfigs := make(map[string]string)
-	for _, sc := range gctx.starScript.inherited {
-		uri := sc.path
+	for _, mi := range gctx.starScript.inherited {
+		uri := mi.path
 		if m, ok := loadedSubConfigs[uri]; ok {
 			// No need to emit load statement, but fix module name.
-			sc.moduleLocalName = m
+			mi.moduleLocalName = m
 			continue
 		}
-		if sc.optional {
+		if mi.optional || mi.missing {
 			uri += "|init"
 		}
 		gctx.newLine()
-		gctx.writef("load(%q, %s = \"init\")", uri, sc.entryName())
-		loadedSubConfigs[uri] = sc.moduleLocalName
+		gctx.writef("load(%q, %s = \"init\")", uri, mi.entryName())
+		loadedSubConfigs[uri] = mi.moduleLocalName
 	}
 	gctx.write("\n")
 }
@@ -293,6 +293,20 @@
 	gctx.writef(`rblf.mk2rbc_error("%s", %q)`, el, message)
 }
 
+func (gctx *generationContext) emitLoadCheck(im inheritedModule) {
+	if !im.needsLoadCheck() {
+		return
+	}
+	gctx.newLine()
+	gctx.writef("if not %s:", im.entryName())
+	gctx.indentLevel++
+	gctx.newLine()
+	gctx.write(`rblf.mkerror("`, gctx.starScript.mkFile, `", "Cannot find %s" % (`)
+	im.pathExpr().emit(gctx)
+	gctx.write("))")
+	gctx.indentLevel--
+}
+
 type knownVariable struct {
 	name      string
 	class     varClass
@@ -746,11 +760,13 @@
 		moduleLocalName += fmt.Sprintf("%d", n)
 	}
 	ctx.moduleNameCount[moduleName] = n + 1
+	_, err := fs.Stat(ctx.script.sourceFS, path)
 	mi := &moduleInfo{
 		path:            modulePath,
 		originalPath:    path,
 		moduleLocalName: moduleLocalName,
 		optional:        optional,
+		missing:         err != nil,
 	}
 	ctx.dependentModules[modulePath] = mi
 	ctx.script.inherited = append(ctx.script.inherited, mi)