private void WriteJsonDeserialize(CodeWriter writer, ObjectType model, JsonSerialization jsonSerialization) { using (writer.Scope($"internal static {model.Type} Deserialize{model.Declaration.Name}({typeof(JsonElement)} element)")) { if (model.Discriminator?.HasDescendants == true) { using (writer.Scope($"if (element.TryGetProperty({model.Discriminator.SerializedName:L}, out {typeof(JsonElement)} discriminator))")) { writer.Line($"switch (discriminator.GetString())"); using (writer.Scope()) { foreach (var implementation in model.Discriminator.Implementations) { writer .Append($"case {implementation.Key:L}: return ") .DeserializeImplementation(implementation.Type.Implementation, w => w.Append($"element")); writer.Line($";"); } } } } writer.DeserializeValue(jsonSerialization, w => w.AppendRaw("element"), (w, v) => w.Line($"return {v};")); } writer.Line(); }
private static void DeserializeIntoVariable(this CodeWriter writer, JsonSerialization serialization, Action <CodeWriter, CodeWriterDelegate> valueCallback, CodeWriterDelegate element) { switch (serialization) { case JsonArraySerialization array: var arrayVariable = new CodeWriterDeclaration("array"); writer.Line($"{array.Type} {arrayVariable:D} = new {array.Type}();"); var collectionItemVariable = new CodeWriterDeclaration("item"); using (writer.Scope($"foreach (var {collectionItemVariable:D} in {element}.EnumerateArray())")) { writer.DeserializeValue( array.ValueSerialization, w => w.Append($"{collectionItemVariable}"), (w, returnValue) => writer.Append($"{arrayVariable}.Add({returnValue});")); } valueCallback(writer, w => w.Append(arrayVariable)); return; case JsonDictionarySerialization dictionary: var dictionaryVariable = new CodeWriterDeclaration("dictionary"); writer.Line($"{dictionary.Type} {dictionaryVariable:D} = new {dictionary.Type}();"); var dictionaryItemVariable = new CodeWriterDeclaration("property"); using (writer.Scope($"foreach (var {dictionaryItemVariable:D} in {element}.EnumerateObject())")) { writer.DeserializeValue( dictionary.ValueSerialization, w => w.Append($"{dictionaryItemVariable}.Value"), (w, returnValue) => writer.Append($"{dictionaryVariable}.Add({dictionaryItemVariable}.Name, {returnValue});")); } valueCallback(writer, w => w.Append(dictionaryVariable)); return; case JsonValueSerialization valueSerialization: valueCallback(writer, w => w.DeserializeValue(valueSerialization, element)); return; } }
private static void DeserializeIntoVariableMayBeObject(this CodeWriter writer, JsonSerialization serialization, Action <CodeWriter, CodeWriterDelegate> valueCallback, CodeWriterDelegate element, Dictionary <ObjectTypeProperty, CodeWriterDeclaration>?propertyVariables = null) { if (serialization is JsonObjectSerialization obj) { var itemVariable = new CodeWriterDeclaration("property"); if (propertyVariables == null) { // this is the first level of object hierarchy // collect all properties and initialize the dictionary propertyVariables = new Dictionary <ObjectTypeProperty, CodeWriterDeclaration>(); CollectProperties(propertyVariables, obj); foreach (var variable in propertyVariables) { var objectTypeProperty = variable.Key; writer.Line($"{objectTypeProperty.Declaration.Type} {variable.Value:D} = default;"); } } var dictionaryVariable = new CodeWriterDeclaration("additionalPropertiesDictionary"); var objAdditionalProperties = obj.AdditionalProperties; if (objAdditionalProperties != null) { writer.Line($"{objAdditionalProperties.Type} {dictionaryVariable:D} = default;"); } using (writer.Scope($"foreach (var {itemVariable:D} in {element}.EnumerateObject())")) { foreach (JsonPropertySerialization property in obj.Properties) { CSharpType?type = property.Property?.Declaration.Type; bool hasNullableType = type != null && type.IsNullable; void WriteNullCheck() { using (writer.Scope($"if ({itemVariable.ActualName}.Value.ValueKind == {typeof(JsonValueKind)}.Null)")) { writer.Append($"continue;"); } } writer.Append($"if({itemVariable.ActualName}.NameEquals({property.Name:L}))"); using (writer.Scope()) { if (hasNullableType) { WriteNullCheck(); } if (property.Property != null) { // Reading a property value writer.DeserializeIntoVariable( property.ValueSerialization, (w, v) => w.Line($"{propertyVariables[property.Property]} = {v};"), w => w.Append($"{itemVariable.ActualName}.Value")); } else { // Reading a nested object writer.DeserializeIntoVariableMayBeObject( property.ValueSerialization, (w, v) => { }, w => w.Append($"{itemVariable.ActualName}.Value"), propertyVariables); } writer.Line($"continue;"); } } if (objAdditionalProperties != null) { writer.Line($"{dictionaryVariable} ??= new {objAdditionalProperties.Type}();"); writer.DeserializeValue( objAdditionalProperties.ValueSerialization, w => w.Append($"{itemVariable}.Value"), (w, v) => w.Line($"{dictionaryVariable}.Add({itemVariable}.Name, {v});")); } } if (objAdditionalProperties != null) { writer.Line($"{propertyVariables[objAdditionalProperties.Property]} = {dictionaryVariable};"); } if (obj.Type != null) { var initializers = new List <ObjectPropertyInitializer>(); foreach (var variable in propertyVariables) { var property = variable.Key; initializers.Add(new ObjectPropertyInitializer( property, new Reference(variable.Value.ActualName, property.Declaration.Type))); } valueCallback(writer, w => w.WriteInitialization((ObjectType)obj.Type.Implementation, initializers)); } } else { writer.DeserializeIntoVariableWithNullHandling(serialization, valueCallback, element); } }