Skip to content

Commit

Permalink
additional properties and raw data field could coexist now, but still…
Browse files Browse the repository at this point in the history
… no filters
  • Loading branch information
ArcturusZhang committed Apr 1, 2024
1 parent 69f05f4 commit 03dc014
Show file tree
Hide file tree
Showing 38 changed files with 373 additions and 284 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ private static MethodBodyStatement[] WriteObject(JsonObjectSerialization seriali
utf8JsonWriter.WriteStartObject(),
WriteProperties(utf8JsonWriter, serialization.Properties, options).ToArray(),
SerializeAdditionalProperties(utf8JsonWriter, options, serialization.AdditionalProperties),
SerializeAdditionalProperties(utf8JsonWriter, options, serialization.RawDataField),
utf8JsonWriter.WriteEndObject()
};

Expand Down Expand Up @@ -506,18 +507,7 @@ private static IEnumerable<MethodBodyStatement> WriteObjectInitialization(JsonOb
// collect all properties and initialize the dictionary
var propertyVariables = new Dictionary<JsonPropertySerialization, VariableReference>();

CollectPropertiesForDeserialization(propertyVariables, serialization.Properties);

var additionalProperties = serialization.AdditionalProperties;
if (additionalProperties != null)
{
propertyVariables.Add(additionalProperties, new VariableReference(additionalProperties.Value.Type, additionalProperties.SerializationConstructorParameterName));
}

if (serialization.RawDataField is { } rawDataField)
{
propertyVariables.Add(rawDataField, new VariableReference(rawDataField.Value.Type, rawDataField.SerializationConstructorParameterName));
}
CollectPropertiesForDeserialization(propertyVariables, serialization);

bool isThisTheDefaultDerivedType = serialization.Type.Equals(serialization.Discriminator?.DefaultObjectType?.Type);

Expand All @@ -538,23 +528,37 @@ private static IEnumerable<MethodBodyStatement> WriteObjectInitialization(JsonOb
}

var shouldTreatEmptyStringAsNull = Configuration.ModelsToTreatEmptyStringAsNull.Contains(serialization.Type.Name);
// TODO -- should also include raw data field here.
var additionalProperties = serialization.AdditionalProperties;
DictionaryExpression? additionalPropertiesDictionary = null;
var rawDataField = serialization.RawDataField;
DictionaryExpression? rawDataFieldDictionary = null;
// if there is additional properties, we need to declare the dictionary first
if (additionalProperties != null)
{
var dictionary = new VariableReference(additionalProperties.ImplementationType, "additionalPropertiesDictionary");
yield return Declare(dictionary, New.Instance(additionalProperties.ImplementationType));
yield return new ForeachStatement("property", element.EnumerateObject(), out var property)
{
DeserializeIntoObjectProperties(serialization.Properties, additionalProperties, new JsonPropertyExpression(property), new DictionaryExpression(additionalProperties.ImplementationType.Arguments[0], additionalProperties.ImplementationType.Arguments[1], dictionary), options, propertyVariables, shouldTreatEmptyStringAsNull).ToArray()
};
yield return Assign(propertyVariables[additionalProperties], dictionary);
yield return Declare("additionalPropertiesDictionary",
new DictionaryExpression(additionalProperties.ImplementationType.Arguments[0], additionalProperties.ImplementationType.Arguments[1], New.Instance(additionalProperties.ImplementationType)),
out additionalPropertiesDictionary);
}
else
// if there is raw data field, we need to declare the dictionary first
if (rawDataField != null)
{
yield return new ForeachStatement("property", element.EnumerateObject(), out var property)
{
DeserializeIntoObjectProperties(serialization.Properties, new JsonPropertyExpression(property), propertyVariables, shouldTreatEmptyStringAsNull, options)
};
yield return Declare("rawDataDictionary",
new DictionaryExpression(rawDataField.ImplementationType.Arguments[0], rawDataField.ImplementationType.Arguments[1], New.Instance(rawDataField.ImplementationType)),
out rawDataFieldDictionary);
}

yield return new ForeachStatement("property", element.EnumerateObject(), out var property)
{
DeserializeIntoObjectProperties(serialization.Properties, new JsonPropertyExpression(property), additionalProperties, additionalPropertiesDictionary, rawDataField, rawDataFieldDictionary, propertyVariables, shouldTreatEmptyStringAsNull, options).ToArray()
};

if (additionalProperties != null && additionalPropertiesDictionary != null)
{
yield return Assign(propertyVariables[additionalProperties], additionalPropertiesDictionary);
}
if (rawDataField != null && rawDataFieldDictionary != null)
{
yield return Assign(propertyVariables[rawDataField], rawDataFieldDictionary);
}

var parameterValues = propertyVariables.ToDictionary(v => v.Key.SerializationConstructorParameterName, v => GetOptional(v.Key, v.Value));
Expand All @@ -566,17 +570,38 @@ private static IEnumerable<MethodBodyStatement> WriteObjectInitialization(JsonOb
}

// TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag.
private static IEnumerable<MethodBodyStatement> DeserializeIntoObjectProperties(IEnumerable<JsonPropertySerialization> propertySerializations, JsonAdditionalPropertiesSerialization additionalPropertiesSerialization, JsonPropertyExpression jsonProperty, DictionaryExpression dictionary, ModelReaderWriterOptionsExpression? options, IReadOnlyDictionary<JsonPropertySerialization, VariableReference> propertyVariables, bool shouldTreatEmptyStringAsNull)
private static IEnumerable<MethodBodyStatement> DeserializeIntoObjectProperties(
IEnumerable<JsonPropertySerialization> propertySerializations, JsonPropertyExpression jsonProperty,
JsonAdditionalPropertiesSerialization? additionalProperties, DictionaryExpression? additionalPropertiesDictionary,
JsonAdditionalPropertiesSerialization? rawDataField, DictionaryExpression? rawDataFieldDictionary,
IReadOnlyDictionary<JsonPropertySerialization, VariableReference> propertyVariables,
bool shouldTreatEmptyStringAsNull,
ModelReaderWriterOptionsExpression? options)
{
yield return DeserializeIntoObjectProperties(propertySerializations, jsonProperty, propertyVariables, shouldTreatEmptyStringAsNull, options);
// in the case here, this line returns an empty statement, we only want the value here
yield return DeserializeValue(additionalPropertiesSerialization.ValueSerialization!, jsonProperty.Value, options, out var value);
var additionalPropertiesStatement = dictionary.Add(jsonProperty.Name, value);

yield return Serializations.WrapInCheckNotWire(
additionalPropertiesSerialization,
options?.Format,
additionalPropertiesStatement);
if (additionalProperties != null && additionalPropertiesDictionary != null)
{
// TODO -- add value filter here
yield return DeserializeValue(additionalProperties.ValueSerialization!, jsonProperty.Value, options, out var value);
var additionalPropertiesStatement = additionalPropertiesDictionary.Add(jsonProperty.Name, value);

yield return Serializations.WrapInCheckNotWire(
additionalProperties,
options?.Format,
additionalPropertiesStatement);
}

if (rawDataField != null && rawDataFieldDictionary != null)
{
yield return DeserializeValue(rawDataField.ValueSerialization!, jsonProperty.Value, options, out var value);
var rawDataFieldStatement = rawDataFieldDictionary.Add(jsonProperty.Name, value);

yield return Serializations.WrapInCheckNotWire(
rawDataField,
options?.Format,
rawDataFieldStatement);
}
}

private static MethodBodyStatement DeserializeIntoObjectProperties(IEnumerable<JsonPropertySerialization> propertySerializations, JsonPropertyExpression jsonProperty, IReadOnlyDictionary<JsonPropertySerialization, VariableReference> propertyVariables, bool shouldTreatEmptyStringAsNull, ModelReaderWriterOptionsExpression? options)
Expand Down Expand Up @@ -712,7 +737,26 @@ private static BoolExpression GetCheckEmptyPropertyValueExpression(JsonPropertyE

}

private static void CollectPropertiesForDeserialization(IDictionary<JsonPropertySerialization, VariableReference> propertyVariables, JsonObjectSerialization serialization)
{
CollectPropertiesForDeserialization(propertyVariables, serialization.Properties);

if (serialization.AdditionalProperties is { } additionalProperties)
{
propertyVariables.Add(additionalProperties, new VariableReference(additionalProperties.Value.Type, additionalProperties.SerializationConstructorParameterName));
}

if (serialization.RawDataField is { } rawDataField)
{
propertyVariables.Add(rawDataField, new VariableReference(rawDataField.Value.Type, rawDataField.SerializationConstructorParameterName));
}
}

/// <summary>
/// Collects a list of properties being read from all level of object hierarchy
/// </summary>
/// <param name="propertyVariables"></param>
/// <param name="jsonProperties"></param>
private static void CollectPropertiesForDeserialization(IDictionary<JsonPropertySerialization, VariableReference> propertyVariables, IEnumerable<JsonPropertySerialization> jsonProperties)
{
foreach (JsonPropertySerialization jsonProperty in jsonProperties)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ protected override IEnumerable<ObjectTypeConstructor> BuildConstructors()

return (additionalPropertiesSerialization, rawDataFieldSerialization);

JsonAdditionalPropertiesSerialization? BuildSerializationForAdditionalProperties(ObjectTypeProperty? additionalPropertiesProperty, InputType? additionalPropertiesValueType)
static JsonAdditionalPropertiesSerialization? BuildSerializationForAdditionalProperties(ObjectTypeProperty? additionalPropertiesProperty, InputType? additionalPropertiesValueType)
{
if (additionalPropertiesProperty is null || additionalPropertiesValueType is null)
return null;
Expand All @@ -622,10 +622,10 @@ protected override IEnumerable<ObjectTypeConstructor> BuildConstructors()
additionalPropertiesProperty,
valueSerialization,
new CSharpType(typeof(Dictionary<,>), additionalPropertiesProperty.Declaration.Type.Arguments),
true);
false);
}

JsonAdditionalPropertiesSerialization? BuildSerializationForRawDataField(ObjectTypeProperty? rawDataField)
static JsonAdditionalPropertiesSerialization? BuildSerializationForRawDataField(ObjectTypeProperty? rawDataField)
{
if (rawDataField is null)
return null;
Expand All @@ -637,7 +637,7 @@ protected override IEnumerable<ObjectTypeConstructor> BuildConstructors()
rawDataField,
valueSerialization,
new CSharpType(typeof(Dictionary<,>), rawDataField.Declaration.Type.Arguments),
false);
true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,24 @@ void IJsonModel<ExtendsFloatAdditionalProperties>.Write(Utf8JsonWriter writer, M
writer.WriteStartObject();
writer.WritePropertyName("id"u8);
writer.WriteNumberValue(Id);
if (options.Format != "W" && AdditionalProperties != null)
foreach (var item in AdditionalProperties)
{
foreach (var item in AdditionalProperties)
writer.WritePropertyName(item.Key);
writer.WriteNumberValue(item.Value);
}
if (options.Format != "W" && _serializedAdditionalRawData != null)
{
foreach (var item in _serializedAdditionalRawData)
{
writer.WritePropertyName(item.Key);
writer.WriteNumberValue(item.Value);
#if NET6_0_OR_GREATER
writer.WriteRawValue(item.Value);
#else
using (JsonDocument document = JsonDocument.Parse(item.Value))
{
JsonSerializer.Serialize(writer, document.RootElement);
}
#endif
}
}
writer.WriteEndObject();
Expand Down Expand Up @@ -64,19 +76,22 @@ internal static ExtendsFloatAdditionalProperties DeserializeExtendsFloatAddition
IDictionary<string, float> additionalProperties = default;
IDictionary<string, BinaryData> serializedAdditionalRawData = default;
Dictionary<string, float> additionalPropertiesDictionary = new Dictionary<string, float>();
Dictionary<string, BinaryData> rawDataDictionary = new Dictionary<string, BinaryData>();
foreach (var property in element.EnumerateObject())
{
if (property.NameEquals("id"u8))
{
id = property.Value.GetSingle();
continue;
}
additionalPropertiesDictionary.Add(property.Name, property.Value.GetSingle());
if (options.Format != "W")
{
additionalPropertiesDictionary.Add(property.Name, property.Value.GetSingle());
rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText()));
}
}
additionalProperties = additionalPropertiesDictionary;
serializedAdditionalRawData = rawDataDictionary;
return new ExtendsFloatAdditionalProperties(id, additionalProperties, serializedAdditionalRawData);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,17 @@ void IJsonModel<ExtendsModelAdditionalProperties>.Write(Utf8JsonWriter writer, M
}

writer.WriteStartObject();
if (options.Format != "W" && AdditionalProperties != null)
foreach (var item in AdditionalProperties)
{
foreach (var item in AdditionalProperties)
{
writer.WritePropertyName(item.Key);
writer.WritePropertyName(item.Key);
#if NET6_0_OR_GREATER
writer.WriteRawValue(item.Value);
#else
using (JsonDocument document = JsonDocument.Parse(item.Value))
{
JsonSerializer.Serialize(writer, document.RootElement);
}
#endif
using (JsonDocument document = JsonDocument.Parse(item.Value))
{
JsonSerializer.Serialize(writer, document.RootElement);
}
#endif
}
writer.WriteEndObject();
}
Expand Down Expand Up @@ -69,10 +66,7 @@ internal static ExtendsModelAdditionalProperties DeserializeExtendsModelAddition
Dictionary<string, BinaryData> additionalPropertiesDictionary = new Dictionary<string, BinaryData>();
foreach (var property in element.EnumerateObject())
{
if (options.Format != "W")
{
additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText()));
}
additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText()));
}
additionalProperties = additionalPropertiesDictionary;
return new ExtendsModelAdditionalProperties(additionalProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,41 @@ void IJsonModel<ExtendsModelArrayAdditionalProperties>.Write(Utf8JsonWriter writ
}

writer.WriteStartObject();
if (options.Format != "W" && AdditionalProperties != null)
foreach (var item in AdditionalProperties)
{
foreach (var item in AdditionalProperties)
writer.WritePropertyName(item.Key);
writer.WriteStartArray();
foreach (var item0 in item.Value)
{
writer.WritePropertyName(item.Key);
writer.WriteStartArray();
foreach (var item0 in item.Value)
if (item0 == null)
{
if (item0 == null)
{
writer.WriteNullValue();
continue;
}
writer.WriteNullValue();
continue;
}
#if NET6_0_OR_GREATER
writer.WriteRawValue(item0);
#else
using (JsonDocument document = JsonDocument.Parse(item0))
{
JsonSerializer.Serialize(writer, document.RootElement);
}
using (JsonDocument document = JsonDocument.Parse(item0))
{
JsonSerializer.Serialize(writer, document.RootElement);
}
#endif
}
writer.WriteEndArray();
}
if (options.Format != "W" && _serializedAdditionalRawData != null)
{
foreach (var item in _serializedAdditionalRawData)
{
writer.WritePropertyName(item.Key);
#if NET6_0_OR_GREATER
writer.WriteRawValue(item.Value);
#else
using (JsonDocument document = JsonDocument.Parse(item.Value))
{
JsonSerializer.Serialize(writer, document.RootElement);
}
writer.WriteEndArray();
#endif
}
}
writer.WriteEndObject();
Expand Down Expand Up @@ -78,6 +90,7 @@ internal static ExtendsModelArrayAdditionalProperties DeserializeExtendsModelArr
IDictionary<string, IList<BinaryData>> additionalProperties = default;
IDictionary<string, BinaryData> serializedAdditionalRawData = default;
Dictionary<string, IList<BinaryData>> additionalPropertiesDictionary = new Dictionary<string, IList<BinaryData>>();
Dictionary<string, BinaryData> rawDataDictionary = new Dictionary<string, BinaryData>();
foreach (var property in element.EnumerateObject())
{
List<BinaryData> array = new List<BinaryData>();
Expand All @@ -92,12 +105,14 @@ internal static ExtendsModelArrayAdditionalProperties DeserializeExtendsModelArr
array.Add(BinaryData.FromString(item.GetRawText()));
}
}
additionalPropertiesDictionary.Add(property.Name, array);
if (options.Format != "W")
{
additionalPropertiesDictionary.Add(property.Name, array);
rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText()));
}
}
additionalProperties = additionalPropertiesDictionary;
serializedAdditionalRawData = rawDataDictionary;
return new ExtendsModelArrayAdditionalProperties(additionalProperties, serializedAdditionalRawData);
}

Expand Down

0 comments on commit 03dc014

Please sign in to comment.