From b1ec3b9307ab7a62d8e85d2ca32dabd82db08651 Mon Sep 17 00:00:00 2001 From: Robert Yokota Date: Wed, 20 Nov 2024 06:29:39 -0800 Subject: [PATCH] AVRO 4091: [C#] Allow previously parsed schemas to be referenced when parsing a schema (#3242) * Allow previously parsed schemas to be referenced when parsing a schema * Incorporate review feedback * Fix comment --- lang/csharp/src/apache/main/Schema/Schema.cs | 17 +++++++++++++++-- .../src/apache/test/Schema/SchemaTests.cs | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lang/csharp/src/apache/main/Schema/Schema.cs b/lang/csharp/src/apache/main/Schema/Schema.cs index 3e54653f015..1910fd46cb1 100644 --- a/lang/csharp/src/apache/main/Schema/Schema.cs +++ b/lang/csharp/src/apache/main/Schema/Schema.cs @@ -228,7 +228,7 @@ internal static Schema ParseJson(JToken jtok, SchemaNames names, string encspace public static Schema Parse(string json) { if (string.IsNullOrEmpty(json)) throw new ArgumentNullException(nameof(json), "json cannot be null."); - return Parse(json.Trim(), new SchemaNames(), null); // standalone schema, so no enclosing namespace + return ParseInternal(json.Trim(), new SchemaNames(), null); // standalone schema, so no enclosing namespace } /// @@ -238,7 +238,20 @@ public static Schema Parse(string json) /// list of named schemas already read /// enclosing namespace of the schema /// new Schema object - internal static Schema Parse(string json, SchemaNames names, string encspace) + public static Schema Parse(string json, SchemaNames names, string encspace = null) + { + if (string.IsNullOrEmpty(json)) throw new ArgumentNullException(nameof(json), "json cannot be null."); + return ParseInternal(json.Trim(), names, encspace); // standalone schema, so no enclosing namespace + } + + /// + /// Parses a JSON string to create a new schema object + /// + /// JSON string + /// list of named schemas already read + /// enclosing namespace of the schema + /// new Schema object + internal static Schema ParseInternal(string json, SchemaNames names, string encspace) { Schema sc = PrimitiveSchema.NewInstance(json); if (null != sc) return sc; diff --git a/lang/csharp/src/apache/test/Schema/SchemaTests.cs b/lang/csharp/src/apache/test/Schema/SchemaTests.cs index 319e9a95be3..221f34eec0d 100644 --- a/lang/csharp/src/apache/test/Schema/SchemaTests.cs +++ b/lang/csharp/src/apache/test/Schema/SchemaTests.cs @@ -408,6 +408,25 @@ public void TestRecordCreationWithRecursiveRecord() Assert.AreEqual(schema, recordSchema.ToString()); } + [TestCase] + public void TestRecordWithNamedReference() + { + string nestedSchema = "{\"name\":\"NestedRecord\",\"type\":\"record\",\"fields\":[{\"name\":\"stringField\",\"type\":\"string\"}]}"; + // The root schema references the nested schema above by name only. + // This mimics tools that allow schemas to have references to other schemas. + string rootSchema = "{\"name\":\"RootRecord\",\"type\":\"record\",\"fields\":[{\"name\": \"nestedField\",\"type\":\"NestedRecord\"}]}"; + + NamedSchema nestedRecord = (NamedSchema) Schema.Parse(nestedSchema); + + SchemaNames names = new SchemaNames(); + names.Add(nestedRecord.SchemaName, nestedRecord); + + // Pass the schema names when parsing the root schema and its reference. + RecordSchema rootRecord = (RecordSchema) Schema.Parse(rootSchema, names); + Assert.AreEqual("RootRecord", rootRecord.Name); + Assert.AreEqual("NestedRecord", rootRecord.Fields[0].Schema.Name); + } + [TestCase("{\"type\":\"enum\",\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}", new string[] { "A", "B" })]