[sdk][meta] Make the common definitions properly reachable.

This required adding a proper id URL to each schema file, which helps
tools locate references.

Bug: DX-1056
Change-Id: I383bab84b23eb7ac3d9fdb3d1a29bf9a13a490d7
diff --git a/build/sdk/meta/banjo_library.json b/build/sdk/meta/banjo_library.json
index 63b0c61..05b069c 100644
--- a/build/sdk/meta/banjo_library.json
+++ b/build/sdk/meta/banjo_library.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/banjo_library.json",
   "description": "A BANJO library",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/cc_prebuilt_library.json b/build/sdk/meta/cc_prebuilt_library.json
index 41b7dc0..2bc017a 100644
--- a/build/sdk/meta/cc_prebuilt_library.json
+++ b/build/sdk/meta/cc_prebuilt_library.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/cc_prebuilt_library.json",
   "description": "A prebuilt C/C++ library",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/cc_source_library.json b/build/sdk/meta/cc_source_library.json
index b8b3b4c..e362f7a 100644
--- a/build/sdk/meta/cc_source_library.json
+++ b/build/sdk/meta/cc_source_library.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/cc_source_library.json",
   "description": "A set of C/C++ sources",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/common.json b/build/sdk/meta/common.json
index bfe973f..b02b160 100644
--- a/build/sdk/meta/common.json
+++ b/build/sdk/meta/common.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/common.json",
   "definitions": {
     "file": {
       "description": "Path to a file from the root of the SDK",
diff --git a/build/sdk/meta/dart_library.json b/build/sdk/meta/dart_library.json
index ede9dea..f364728 100644
--- a/build/sdk/meta/dart_library.json
+++ b/build/sdk/meta/dart_library.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/dart_library.json",
   "description": "A Dart library",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/documentation.json b/build/sdk/meta/documentation.json
index 9211b2f..9b4c4d9 100644
--- a/build/sdk/meta/documentation.json
+++ b/build/sdk/meta/documentation.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/documentation.json",
   "description": "A set of documents",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/fidl_library.json b/build/sdk/meta/fidl_library.json
index 25581b3..41b9569 100644
--- a/build/sdk/meta/fidl_library.json
+++ b/build/sdk/meta/fidl_library.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/fidl_library.json",
   "description": "A FIDL library",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/host_tool.json b/build/sdk/meta/host_tool.json
index d4ac53a..300b799 100644
--- a/build/sdk/meta/host_tool.json
+++ b/build/sdk/meta/host_tool.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/host_tool.json",
   "description": "A host tool",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/image.json b/build/sdk/meta/image.json
index e6a3e3a2..a6b98e8 100644
--- a/build/sdk/meta/image.json
+++ b/build/sdk/meta/image.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/image.json",
   "description": "A target image",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/loadable_module.json b/build/sdk/meta/loadable_module.json
index d93c1b1..187f739 100644
--- a/build/sdk/meta/loadable_module.json
+++ b/build/sdk/meta/loadable_module.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/loadable_module.json",
   "description": "A collection of object files that can be loaded at runtime",
   "type": "object",
   "allOf": [
diff --git a/build/sdk/meta/manifest.json b/build/sdk/meta/manifest.json
index 0bab9aa..0145c2d 100644
--- a/build/sdk/meta/manifest.json
+++ b/build/sdk/meta/manifest.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/manifest.json",
   "description": "The manifest describing the contents of the SDK",
   "type": "object",
   "properties": {
diff --git a/build/sdk/meta/src/common.rs b/build/sdk/meta/src/common.rs
new file mode 100644
index 0000000..95398d4
--- /dev/null
+++ b/build/sdk/meta/src/common.rs
@@ -0,0 +1,12 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use serde_derive::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "lowercase")]
+pub enum TargetArchitecture {
+    Arm64,
+    X64,
+}
diff --git a/build/sdk/meta/src/json.rs b/build/sdk/meta/src/json.rs
index d316419..5828292 100644
--- a/build/sdk/meta/src/json.rs
+++ b/build/sdk/meta/src/json.rs
@@ -41,8 +41,15 @@
     fn validate(&self) -> Result<()> {
         let schema = from_str(Self::get_schema())?;
         let mut scope = json_schema::Scope::new();
+
+        // Add the schema including all the common definitions.
+        let common_schema = from_str(include_str!("../common.json"))?;
+        scope
+            .compile(common_schema, true)
+            .map_err(Error::SchemaInvalid)?;
+
         let validator = scope
-            .compile_and_return(schema, false)
+            .compile_and_return(schema, true)
             .map_err(Error::SchemaInvalid)?;
         let value = to_value(self)?;
         let result = validator.validate(&value);
@@ -66,3 +73,39 @@
         Ok(to_string(self)?)
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use serde_derive::{Deserialize, Serialize};
+
+    use super::*;
+
+    #[derive(Deserialize, Serialize)]
+    struct Metadata {
+        target: String,
+    }
+
+    impl JsonObject for Metadata {
+        fn get_schema() -> &'static str {
+            r#"{
+                "$schema": "http://json-schema.org/draft-04/schema#",
+                "id": "http://fuchsia.com/schemas/sdk/test_metadata.json",
+                "properties": {
+                    "target": {
+                        "$ref": "common.json#/definitions/target_arch"
+                    }
+                }
+            }"#
+        }
+    }
+
+    #[test]
+    /// Checks that references to common.json are properly resolved.
+    fn test_common_reference() {
+        let metadata = Metadata {
+            target: "y128".to_string(), // Not a valid architecture.
+        };
+        let result = metadata.validate();
+        assert!(result.is_err(), "Validation did not respect common schema.");
+    }
+}
diff --git a/build/sdk/meta/src/lib.rs b/build/sdk/meta/src/lib.rs
index 7a4a48d..f195d15 100644
--- a/build/sdk/meta/src/lib.rs
+++ b/build/sdk/meta/src/lib.rs
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+mod common;
 mod json;
 mod manifest;
 
+pub use crate::common::*;
 pub use crate::json::JsonObject;
 pub use crate::manifest::*;
diff --git a/build/sdk/meta/src/manifest.rs b/build/sdk/meta/src/manifest.rs
index 8aafb04..dd4ee85 100644
--- a/build/sdk/meta/src/manifest.rs
+++ b/build/sdk/meta/src/manifest.rs
@@ -6,15 +6,9 @@
 
 use serde_derive::{Deserialize, Serialize};
 
+use crate::common::TargetArchitecture;
 use crate::json::JsonObject;
 
-#[derive(Serialize, Deserialize, Debug)]
-#[serde(rename_all = "lowercase")]
-pub enum TargetArchitecture {
-    Arm64,
-    X64,
-}
-
 #[derive(Serialize, Deserialize, Debug, Default)]
 #[serde(deny_unknown_fields)]
 pub struct Architectures {
diff --git a/build/sdk/meta/sysroot.json b/build/sdk/meta/sysroot.json
index ee44064..9924ce2 100644
--- a/build/sdk/meta/sysroot.json
+++ b/build/sdk/meta/sysroot.json
@@ -1,4 +1,6 @@
 {
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/sysroot.json",
   "description": "The sysroot",
   "type": "object",
   "allOf": [