示例#1
0
        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);
            }
        }