Refactor additional properties in models (#4400)
Contributes to https://github.com/microsoft/typespec/issues/4007 by refactoring how additional properties are generated. The serialization changes will be included in follow up PR(s).
This commit is contained in:
Родитель
5fa9d4c27c
Коммит
af9a2eb36a
|
@ -26,7 +26,8 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
/// </summary>
|
||||
internal class MrwSerializationTypeDefinition : TypeProvider
|
||||
{
|
||||
private const string PrivateAdditionalPropertiesPropertyName = "_serializedAdditionalRawData";
|
||||
private const string AdditionalBinaryDataPropertiesFieldName = "_additionalBinaryDataProperties";
|
||||
private const string AdditionBinaryDataPropertiesPropertyName = "AdditionalBinaryDataProperties";
|
||||
private const string JsonModelWriteCoreMethodName = "JsonModelWriteCore";
|
||||
private const string JsonModelCreateCoreMethodName = "JsonModelCreateCore";
|
||||
private const string PersistableModelWriteCoreMethodName = "PersistableModelWriteCore";
|
||||
|
@ -51,6 +52,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
private readonly ModelProvider _model;
|
||||
private readonly InputModelType _inputModel;
|
||||
private readonly FieldProvider? _rawDataField;
|
||||
private readonly PropertyProvider? _additionalBinaryDataProperty;
|
||||
private readonly bool _isStruct;
|
||||
private ConstructorProvider? _serializationConstructor;
|
||||
// Flag to determine if the model should override the serialization methods
|
||||
|
@ -67,7 +69,10 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
_jsonModelObjectInterface = _isStruct ? (CSharpType)typeof(IJsonModel<object>) : null;
|
||||
_persistableModelTInterface = new CSharpType(typeof(IPersistableModel<>), interfaceType.Type);
|
||||
_persistableModelObjectInterface = _isStruct ? (CSharpType)typeof(IPersistableModel<object>) : null;
|
||||
_rawDataField = _model.Fields.FirstOrDefault(f => f.Name == PrivateAdditionalPropertiesPropertyName);
|
||||
_rawDataField = _model.Fields.FirstOrDefault(f => f.Name == AdditionalBinaryDataPropertiesFieldName);
|
||||
_additionalBinaryDataProperty = _model.Properties.FirstOrDefault(
|
||||
p => p.Name == AdditionBinaryDataPropertiesPropertyName
|
||||
|| p.Name == "AdditionalProperties" && p.Type.IsDictionary && p.Type.ElementType.Equals(typeof(BinaryData)));
|
||||
_shouldOverrideMethods = _model.Type.BaseType != null && _model.Type.BaseType is { IsFrameworkType: false };
|
||||
_utf8JsonWriterSnippet = _utf8JsonWriterParameter.As<Utf8JsonWriter>();
|
||||
_mrwOptionsParameterSnippet = _serializationOptionsParameter.As<ModelReaderWriterOptions>();
|
||||
|
@ -567,10 +572,10 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
Debug.Assert(parameter.Field != null);
|
||||
var field = parameter.Field;
|
||||
var fieldRef = field.AsVariableExpression;
|
||||
if (field.Name == PrivateAdditionalPropertiesPropertyName)
|
||||
if (field.Name == AdditionalBinaryDataPropertiesFieldName)
|
||||
{
|
||||
// the raw data is kind of different because we assign it with an instance, not like others properties/fields
|
||||
// IDictionary<string, BinaryData> serializedAdditionalRawData = new Dictionary<string, BinaryData>();
|
||||
// IDictionary<string, BinaryData> additionalBinaryDataProperties = new Dictionary<string, BinaryData>();
|
||||
propertyDeclarationStatements.Add(Declare(fieldRef, new DictionaryExpression(field.Type, New.Instance(field.Type.PropertyInitializationType))));
|
||||
}
|
||||
else
|
||||
|
@ -729,7 +734,16 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
}
|
||||
|
||||
// deserialize the raw data properties
|
||||
if (_rawDataField != null)
|
||||
if (_additionalBinaryDataProperty != null)
|
||||
{
|
||||
var elementType = _additionalBinaryDataProperty.Type.Arguments[1].FrameworkType;
|
||||
var rawDataDeserializationValue = GetValueTypeDeserializationExpression(elementType, jsonProperty.Value(), SerializationFormat.Default);
|
||||
propertyDeserializationStatements.Add(new IfStatement(_isNotEqualToWireConditionSnippet)
|
||||
{
|
||||
_additionalBinaryDataProperty.AsVariableExpression.AsDictionary(_additionalBinaryDataProperty.Type).Add(jsonProperty.Name(), rawDataDeserializationValue)
|
||||
});
|
||||
}
|
||||
else if (_rawDataField != null)
|
||||
{
|
||||
var elementType = _rawDataField.Type.Arguments[1].FrameworkType;
|
||||
var rawDataDeserializationValue = GetValueTypeDeserializationExpression(elementType, jsonProperty.Value(), SerializationFormat.Default);
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace sample.namespace.Models
|
|||
}
|
||||
writer.WritePropertyName("camelCase"u8);
|
||||
writer.WriteStringValue(CamelCase);
|
||||
if (((options.Format != "W") && (_serializedAdditionalRawData != null)))
|
||||
if (((options.Format != "W") && (_additionalBinaryDataProperties != null)))
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace sample.namespace.Models
|
|||
}
|
||||
writer.WritePropertyName("kebab-case"u8);
|
||||
writer.WriteStringValue(KebabCase);
|
||||
if (((options.Format != "W") && (_serializedAdditionalRawData != null)))
|
||||
if (((options.Format != "W") && (_additionalBinaryDataProperties != null)))
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace sample.namespace.Models
|
|||
}
|
||||
writer.WritePropertyName("PascalCase"u8);
|
||||
writer.WriteStringValue(PascalCase);
|
||||
if (((options.Format != "W") && (_serializedAdditionalRawData != null)))
|
||||
if (((options.Format != "W") && (_additionalBinaryDataProperties != null)))
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace sample.namespace.Models
|
|||
}
|
||||
writer.WritePropertyName("snake_case"u8);
|
||||
writer.WriteStringValue(SnakeCase);
|
||||
if (((options.Format != "W") && (_serializedAdditionalRawData != null)))
|
||||
if (((options.Format != "W") && (_additionalBinaryDataProperties != null)))
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
internal class ModelFactoryProvider : TypeProvider
|
||||
{
|
||||
private const string ModelFactorySuffix = "ModelFactory";
|
||||
private const string AdditionalRawDataParameterName = "serializedAdditionalRawData";
|
||||
private const string AdditionalBinaryDataParameterName = "additionalBinaryDataProperties";
|
||||
|
||||
private readonly IEnumerable<InputModelType> _models;
|
||||
|
||||
|
@ -84,7 +84,7 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
MethodSignatureModifiers.Static | MethodSignatureModifiers.Public,
|
||||
modelProvider.Type,
|
||||
$"A new {modelProvider.Type:C} instance for mocking.",
|
||||
GetParameters(modelCtor));
|
||||
GetParameters(modelCtor, modelProvider.SupportsBinaryDataAdditionalProperties));
|
||||
|
||||
var docs = new XmlDocProvider();
|
||||
docs.Summary = modelProvider.XmlDocs?.Summary;
|
||||
|
@ -98,7 +98,7 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
[
|
||||
.. GetCollectionInitialization(signature),
|
||||
MethodBodyStatement.EmptyLine,
|
||||
Return(New.Instance(typeToInstantiate.Type, [.. GetCtorArgs(signature, modelCtor.Signature)]))
|
||||
Return(New.Instance(typeToInstantiate.Type, [.. GetCtorArgs(signature, modelCtor.Signature, modelProvider.SupportsBinaryDataAdditionalProperties)]))
|
||||
]);
|
||||
|
||||
methods.Add(new MethodProvider(signature, statements, this, docs));
|
||||
|
@ -108,7 +108,8 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
|
||||
private static IReadOnlyList<ValueExpression> GetCtorArgs(
|
||||
MethodSignature signature,
|
||||
ConstructorSignature modelCtorFullSignature)
|
||||
ConstructorSignature modelCtorFullSignature,
|
||||
bool supportsBinaryDataAdditionalProps)
|
||||
{
|
||||
var expressions = new List<ValueExpression>(signature.Parameters.Count);
|
||||
for (int i = 0; i < signature.Parameters.Count; i++)
|
||||
|
@ -129,8 +130,8 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
}
|
||||
}
|
||||
|
||||
var modelContainsAdditionalRawData = modelCtorFullSignature.Parameters.Any(p => p.Name.Equals(AdditionalRawDataParameterName));
|
||||
if (modelContainsAdditionalRawData)
|
||||
var modelContainsAdditionalRawData = modelCtorFullSignature.Parameters.Any(p => p.Name.Equals(AdditionalBinaryDataParameterName));
|
||||
if (modelContainsAdditionalRawData && !supportsBinaryDataAdditionalProps)
|
||||
{
|
||||
expressions.Add(Null);
|
||||
}
|
||||
|
@ -151,13 +152,15 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
return [.. statements];
|
||||
}
|
||||
|
||||
private static IReadOnlyList<ParameterProvider> GetParameters(ConstructorProvider modelFullConstructor)
|
||||
private static IReadOnlyList<ParameterProvider> GetParameters(
|
||||
ConstructorProvider modelFullConstructor,
|
||||
bool supportsBinaryDataAdditionalProps)
|
||||
{
|
||||
var modelCtorParams = modelFullConstructor.Signature.Parameters;
|
||||
var parameters = new List<ParameterProvider>(modelCtorParams.Count);
|
||||
foreach (var param in modelCtorParams)
|
||||
{
|
||||
if (param.Name.Equals(AdditionalRawDataParameterName))
|
||||
if (param.Name.Equals(AdditionalBinaryDataParameterName) && !supportsBinaryDataAdditionalProps)
|
||||
continue;
|
||||
|
||||
parameters.Add(GetModelFactoryParam(param));
|
||||
|
|
|
@ -17,18 +17,19 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
{
|
||||
public sealed class ModelProvider : TypeProvider
|
||||
{
|
||||
private const string PrivateAdditionalPropertiesPropertyDescription = "Keeps track of any properties unknown to the library.";
|
||||
private const string PrivateAdditionalPropertiesPropertyName = "_serializedAdditionalRawData";
|
||||
private const string AdditionalPropertiesPropertyName = "AdditionalProperties";
|
||||
private const string AdditionalBinaryDataPropsFieldDescription = "Keeps track of any properties unknown to the library.";
|
||||
private const string AdditionalBinaryDataPropsFieldName = "_additionalBinaryDataProperties";
|
||||
private const string DefaultAdditionalPropertiesPropertyName = "AdditionalProperties";
|
||||
private readonly InputModelType _inputModel;
|
||||
|
||||
protected override FormattableString Description { get; }
|
||||
|
||||
private readonly CSharpType _privateAdditionalRawDataPropertyType = typeof(IDictionary<string, BinaryData>);
|
||||
private readonly CSharpType _additionalBinaryDataPropsFieldType = typeof(IDictionary<string, BinaryData>);
|
||||
private readonly Type _additionalPropsUnknownType = typeof(BinaryData);
|
||||
private readonly Lazy<TypeProvider?>? _baseTypeProvider;
|
||||
private FieldProvider? _rawDataField;
|
||||
private PropertyProvider? _additionalProperties;
|
||||
private List<FieldProvider>? _additionalPropertyFields;
|
||||
private List<PropertyProvider>? _additionalPropertyProperties;
|
||||
private ModelProvider? _baseModelProvider;
|
||||
private ConstructorProvider? _fullConstructor;
|
||||
|
||||
|
@ -70,8 +71,9 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
private ModelProvider? BaseModelProvider
|
||||
=> _baseModelProvider ??= (_baseTypeProvider?.Value is ModelProvider baseModelProvider ? baseModelProvider : null);
|
||||
private FieldProvider? RawDataField => _rawDataField ??= BuildRawDataField();
|
||||
private PropertyProvider? AdditionalPropertiesProperty => _additionalProperties ??= BuildAdditionalProperties();
|
||||
|
||||
private List<FieldProvider> AdditionalPropertyFields => _additionalPropertyFields ??= BuildAdditionalPropertyFields();
|
||||
private List<PropertyProvider> AdditionalPropertyProperties => _additionalPropertyProperties ??= BuildAdditionalPropertyProperties();
|
||||
internal bool SupportsBinaryDataAdditionalProperties => AdditionalPropertyProperties.Any(p => p.Type.ElementType.Equals(_additionalPropsUnknownType));
|
||||
public ConstructorProvider FullConstructor => _fullConstructor ??= BuildFullConstructor();
|
||||
|
||||
protected override string GetNamespace() => CodeModelPlugin.Instance.Configuration.ModelNamespace;
|
||||
|
@ -150,6 +152,13 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
{
|
||||
fields.Add(RawDataField);
|
||||
}
|
||||
|
||||
// add fields for additional properties
|
||||
if (AdditionalPropertyFields.Count > 0)
|
||||
{
|
||||
fields.AddRange(AdditionalPropertyFields);
|
||||
}
|
||||
|
||||
foreach (var property in _inputModel.Properties)
|
||||
{
|
||||
if (property.IsDiscriminator)
|
||||
|
@ -171,6 +180,112 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
return [.. fields];
|
||||
}
|
||||
|
||||
private List<FieldProvider> BuildAdditionalPropertyFields()
|
||||
{
|
||||
var fields = new List<FieldProvider>();
|
||||
|
||||
if (_inputModel.AdditionalProperties != null)
|
||||
{
|
||||
var valueType = CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(_inputModel.AdditionalProperties);
|
||||
if (valueType != null)
|
||||
{
|
||||
if (valueType.IsUnion)
|
||||
{
|
||||
foreach (var unionType in valueType.UnionItemTypes)
|
||||
{
|
||||
AddFieldForAdditionalProperties(unionType, fields);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddFieldForAdditionalProperties(valueType, fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
private void AddFieldForAdditionalProperties(CSharpType valueType, List<FieldProvider> fields)
|
||||
{
|
||||
var originalType = new CSharpType(typeof(IDictionary<,>), typeof(string), valueType);
|
||||
var additionalPropsType = ReplaceUnverifiableType(originalType);
|
||||
|
||||
if (!additionalPropsType.Equals(_additionalBinaryDataPropsFieldType))
|
||||
{
|
||||
fields.Add(new FieldProvider(
|
||||
FieldModifiers.Private,
|
||||
additionalPropsType,
|
||||
BuildAdditionalTypePropertiesFieldName(additionalPropsType.ElementType),
|
||||
this));
|
||||
}
|
||||
}
|
||||
|
||||
private List<PropertyProvider> BuildAdditionalPropertyProperties()
|
||||
{
|
||||
var additionalPropertiesFieldCount = AdditionalPropertyFields.Count;
|
||||
var properties = new List<PropertyProvider>(additionalPropertiesFieldCount + 1);
|
||||
bool containsAdditionalTypeProperties = false;
|
||||
|
||||
for (int i = 0; i < additionalPropertiesFieldCount; i++)
|
||||
{
|
||||
var field = AdditionalPropertyFields[i];
|
||||
var propertyType = !_inputModel.Usage.HasFlag(InputModelTypeUsage.Input) ? field.Type.OutputType : field.Type;
|
||||
var assignment = propertyType.IsReadOnlyDictionary
|
||||
? new ExpressionPropertyBody(New.ReadOnlyDictionary(propertyType.Arguments[0], propertyType.ElementType, field))
|
||||
: new ExpressionPropertyBody(field);
|
||||
|
||||
properties.Add(new(
|
||||
null,
|
||||
MethodSignatureModifiers.Public,
|
||||
propertyType,
|
||||
i == 0 ? DefaultAdditionalPropertiesPropertyName : field.Name.ToCleanName(),
|
||||
assignment,
|
||||
this));
|
||||
containsAdditionalTypeProperties = true;
|
||||
}
|
||||
|
||||
if (RawDataField == null || _inputModel.AdditionalProperties == null)
|
||||
{
|
||||
return properties;
|
||||
}
|
||||
|
||||
var apValueType = CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(_inputModel.AdditionalProperties);
|
||||
if (apValueType == null)
|
||||
{
|
||||
return properties;
|
||||
}
|
||||
|
||||
// add public property for raw binary data if the model supports additional binary data properties
|
||||
var originalType = new CSharpType(typeof(IDictionary<,>), typeof(string), apValueType);
|
||||
var additionalPropsType = ReplaceUnverifiableType(originalType);
|
||||
var shouldAddPropForUnionType = additionalPropsType.ElementType.IsUnion
|
||||
&& additionalPropsType.ElementType.UnionItemTypes.Any(t => !t.IsFrameworkType);
|
||||
|
||||
if (shouldAddPropForUnionType || (!apValueType.IsUnion && additionalPropsType.Equals(_additionalBinaryDataPropsFieldType)))
|
||||
{
|
||||
var name = !containsAdditionalTypeProperties
|
||||
? DefaultAdditionalPropertiesPropertyName
|
||||
: RawDataField.Name.ToCleanName();
|
||||
var type = !_inputModel.Usage.HasFlag(InputModelTypeUsage.Input)
|
||||
? additionalPropsType.OutputType
|
||||
: additionalPropsType;
|
||||
var assignment = type.IsReadOnlyDictionary
|
||||
? new ExpressionPropertyBody(New.ReadOnlyDictionary(type.Arguments[0], type.ElementType, RawDataField))
|
||||
: new ExpressionPropertyBody(RawDataField);
|
||||
|
||||
properties.Add(new(
|
||||
null,
|
||||
MethodSignatureModifiers.Public,
|
||||
type,
|
||||
name,
|
||||
assignment,
|
||||
this));
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private Dictionary<InputModelType, Dictionary<string, InputModelProperty>>? _inputDerivedProperties;
|
||||
private Dictionary<InputModelType, Dictionary<string, InputModelProperty>> InputDerivedProperties => _inputDerivedProperties ??= BuildDerivedProperties();
|
||||
|
||||
|
@ -254,9 +369,9 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
properties.Add(outputProperty);
|
||||
}
|
||||
|
||||
if (AdditionalPropertiesProperty != null)
|
||||
if (AdditionalPropertyProperties.Count > 0)
|
||||
{
|
||||
properties.Add(AdditionalPropertiesProperty);
|
||||
properties.AddRange(AdditionalPropertyProperties);
|
||||
}
|
||||
|
||||
return [.. properties];
|
||||
|
@ -368,9 +483,13 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
|
||||
if (!isPrimaryConstructor)
|
||||
{
|
||||
if (AdditionalPropertiesProperty != null)
|
||||
constructorParameters.Add(AdditionalPropertiesProperty.AsParameter);
|
||||
if (RawDataField != null)
|
||||
foreach (var property in AdditionalPropertyProperties)
|
||||
{
|
||||
constructorParameters.Add(property.AsParameter);
|
||||
}
|
||||
|
||||
// only add the raw data field if it has not already been added as a parameter for BinaryData additional properties
|
||||
if (RawDataField != null && !SupportsBinaryDataAdditionalProperties)
|
||||
constructorParameters.Add(RawDataField.AsParameter);
|
||||
}
|
||||
|
||||
|
@ -522,18 +641,30 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
}
|
||||
}
|
||||
|
||||
if (AdditionalPropertiesProperty != null)
|
||||
// handle additional properties
|
||||
foreach (var property in AdditionalPropertyProperties)
|
||||
{
|
||||
var assignment = isPrimaryConstructor
|
||||
? AdditionalPropertiesProperty.Assign(New.Instance(AdditionalPropertiesProperty.Type.PropertyInitializationType))
|
||||
: AdditionalPropertiesProperty.Assign(AdditionalPropertiesProperty.AsParameter);
|
||||
// find the corresponding backing field for the property
|
||||
var backingField = AdditionalPropertyFields.FirstOrDefault(f => f.Type.ElementType.Equals(property.Type.ElementType))
|
||||
?? (RawDataField != null && property.Type.ElementType.Equals(RawDataField.Type.ElementType) ? RawDataField : null);
|
||||
|
||||
methodBodyStatements.Add(assignment.Terminate());
|
||||
if (backingField != null)
|
||||
{
|
||||
var assignment = isPrimaryConstructor
|
||||
? backingField.Assign(New.Instance(backingField.Type.PropertyInitializationType))
|
||||
: backingField.Assign(property.AsParameter);
|
||||
|
||||
methodBodyStatements.Add(assignment.Terminate());
|
||||
}
|
||||
}
|
||||
|
||||
if (!isPrimaryConstructor && RawDataField != null)
|
||||
if (RawDataField != null)
|
||||
{
|
||||
methodBodyStatements.Add(RawDataField.Assign(RawDataField.AsParameter).Terminate());
|
||||
// initialize the raw data field in the serialization constructor if the model does not explicitly support AP of binary data.
|
||||
if (!isPrimaryConstructor && !SupportsBinaryDataAdditionalProperties)
|
||||
{
|
||||
methodBodyStatements.Add(RawDataField.Assign(RawDataField.AsParameter).Terminate());
|
||||
}
|
||||
}
|
||||
|
||||
return methodBodyStatements;
|
||||
|
@ -564,17 +695,6 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
return null;
|
||||
}
|
||||
|
||||
// validate if the additional properties property exists & if its' value type is also BinaryData
|
||||
// if so, we do not have to have a raw data field since the additional properties property will be used for serialization
|
||||
// of raw data
|
||||
if ((AdditionalPropertiesProperty != null
|
||||
&& AdditionalPropertiesProperty.Type.ElementType.Equals(_additionalPropsUnknownType, ignoreNullable: true)) ||
|
||||
(BaseModelProvider?.AdditionalPropertiesProperty != null
|
||||
&& BaseModelProvider.AdditionalPropertiesProperty.Type.ElementType.Equals(_additionalPropsUnknownType, ignoreNullable: true)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var modifiers = FieldModifiers.Private;
|
||||
if (!DeclarationModifiers.HasFlag(TypeSignatureModifiers.Sealed))
|
||||
{
|
||||
|
@ -583,40 +703,14 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
|
||||
var rawDataField = new FieldProvider(
|
||||
modifiers: modifiers,
|
||||
type: _privateAdditionalRawDataPropertyType,
|
||||
description: FormattableStringHelpers.FromString(PrivateAdditionalPropertiesPropertyDescription),
|
||||
name: PrivateAdditionalPropertiesPropertyName,
|
||||
type: _additionalBinaryDataPropsFieldType,
|
||||
description: FormattableStringHelpers.FromString(AdditionalBinaryDataPropsFieldDescription),
|
||||
name: AdditionalBinaryDataPropsFieldName,
|
||||
enclosingType: this);
|
||||
|
||||
return rawDataField;
|
||||
}
|
||||
|
||||
private PropertyProvider? BuildAdditionalProperties()
|
||||
{
|
||||
var additionalProperties = _inputModel.AdditionalProperties;
|
||||
if (additionalProperties is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var valueType = CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(additionalProperties);
|
||||
if (valueType is null)
|
||||
throw new InvalidOperationException($"Failed to create CSharpType for additional properties of model {_inputModel.Name}");
|
||||
|
||||
var originalType = new CSharpType(typeof(IDictionary<,>), typeof(string), valueType);
|
||||
var additionalPropsType = !_inputModel.Usage.HasFlag(InputModelTypeUsage.Input)
|
||||
? ReplaceUnverifiableType(originalType).OutputType
|
||||
: ReplaceUnverifiableType(originalType);
|
||||
|
||||
return new PropertyProvider(
|
||||
null,
|
||||
MethodSignatureModifiers.Public,
|
||||
additionalPropsType,
|
||||
name: AdditionalPropertiesPropertyName,
|
||||
new AutoPropertyBody(false),
|
||||
enclosingType: this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces unverifiable types, types that do not have value kind checks during deserialization of additional properties,
|
||||
/// with the corresponding verifiable types. By default, BinaryData is used as the value type for unknown additional properties.
|
||||
|
@ -636,6 +730,19 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
};
|
||||
}
|
||||
|
||||
private static string BuildAdditionalTypePropertiesFieldName(CSharpType additionalPropertiesValueType)
|
||||
{
|
||||
var name = additionalPropertiesValueType.Name;
|
||||
|
||||
while (additionalPropertiesValueType.IsCollection)
|
||||
{
|
||||
additionalPropertiesValueType = additionalPropertiesValueType.ElementType;
|
||||
name += additionalPropertiesValueType.Name;
|
||||
}
|
||||
|
||||
return $"_additional{name.ToCleanName()}Properties";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The set of known verifiable additional property value types that have value kind checks during deserialization.
|
||||
/// </summary>
|
||||
|
|
|
@ -52,6 +52,8 @@ namespace Microsoft.Generator.CSharp.Snippets
|
|||
public static IndexableExpression Array(CSharpType? elementType, bool isInline, bool isStackAlloc, params ValueExpression[] items) => new(new NewArrayExpression(elementType, new ArrayInitializerExpression(items, isInline), IsStackAlloc: isStackAlloc));
|
||||
public static IndexableExpression Array(CSharpType? elementType, ValueExpression size) => new(new NewArrayExpression(elementType, Size: size));
|
||||
|
||||
public static DictionaryExpression ReadOnlyDictionary(CSharpType keyType, CSharpType valueType, params ValueExpression[] items)
|
||||
=> new(new NewInstanceExpression(new CSharpType(typeof(System.Collections.ObjectModel.ReadOnlyDictionary<,>), keyType, valueType), items));
|
||||
public static DictionaryExpression Dictionary(CSharpType keyType, CSharpType valueType)
|
||||
=> new(new NewInstanceExpression(new CSharpType(typeof(Dictionary<,>), keyType, valueType), []));
|
||||
public static DictionaryExpression Dictionary(CSharpType keyType, CSharpType valueType, IReadOnlyDictionary<ValueExpression, ValueExpression> values)
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelFactories
|
|||
Assert.IsNotNull(model, "Null ModelProvider found");
|
||||
var method = modelFactory.Methods.FirstOrDefault(m => m.Signature.Name == model!.Name);
|
||||
Assert.IsNotNull(method);
|
||||
foreach (var property in model!.Properties.Where(p => p.Type.IsDictionary))
|
||||
foreach (var property in model!.Properties.Where(p => p.Type.IsDictionary && !p.Name.StartsWith("Additional")))
|
||||
{
|
||||
var parameter = method!.Signature.Parameters.FirstOrDefault(p => p.Name == property.Name.ToVariableName());
|
||||
Assert.IsNotNull(parameter);
|
||||
|
@ -97,6 +97,30 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelFactories
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AdditionalPropertiesParamShape()
|
||||
{
|
||||
var modelFactory = ModelFactoryProvider.FromInputLibrary();
|
||||
var models = ModelList.Select(CodeModelPlugin.Instance.TypeFactory.CreateModel);
|
||||
foreach (var model in models)
|
||||
{
|
||||
if (!model!.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public))
|
||||
continue; //skip internal models
|
||||
|
||||
Assert.IsNotNull(model, "Null ModelProvider found");
|
||||
var method = modelFactory.Methods.FirstOrDefault(m => m.Signature.Name == model!.Name);
|
||||
Assert.IsNotNull(method);
|
||||
foreach (var _ in model!.Properties.Where(p => p.Type.IsDictionary && p.Name.StartsWith("Additional")))
|
||||
{
|
||||
var parameter = method!.Signature.Parameters.FirstOrDefault(p => p.Name == "additionalProperties");
|
||||
Assert.IsNotNull(parameter);
|
||||
Assert.IsTrue(parameter!.Type.IsFrameworkType);
|
||||
Assert.AreEqual(typeof(IDictionary<,>), parameter!.Type.FrameworkType);
|
||||
Assert.IsTrue(parameter.Type.ContainsBinaryData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModelFactoryName()
|
||||
{
|
||||
|
@ -106,6 +130,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelFactories
|
|||
|
||||
private static InputModelType[] GetTestModels()
|
||||
{
|
||||
InputType additionalPropertiesUnknown = InputPrimitiveType.Any;
|
||||
InputModelProperty[] properties =
|
||||
[
|
||||
InputFactory.Property("StringProp", InputPrimitiveType.String),
|
||||
|
@ -127,6 +152,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelFactories
|
|||
InputFactory.Model("PublicModel2", properties: properties),
|
||||
derivedModel,
|
||||
InputFactory.Model("BaseModel", properties: properties, derivedModels: [derivedModel]),
|
||||
InputFactory.Model("ModelWithUnknownAdditionalProperties", properties: properties, additionalProperties: additionalPropertiesUnknown),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
|
|||
Assert.AreEqual(2, catModel!.Constructors.Count);
|
||||
var serializationCtor = catModel.Constructors.FirstOrDefault(c => c.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Internal));
|
||||
Assert.IsNotNull(serializationCtor);
|
||||
Assert.AreEqual("serializedAdditionalRawData", serializationCtor!.Signature.Parameters.Last().Name);
|
||||
Assert.AreEqual("additionalBinaryDataProperties", serializationCtor!.Signature.Parameters.Last().Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -256,7 +256,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
|
|||
Assert.AreEqual(new CSharpType(typeof(string), true), secondaryCtorParameters[1].Type);
|
||||
Assert.AreEqual("additionalProperties", secondaryCtorParameters[2].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, string>)), secondaryCtorParameters[2].Type);
|
||||
Assert.AreEqual("serializedAdditionalRawData", secondaryCtorParameters[3].Name);
|
||||
Assert.AreEqual("additionalBinaryDataProperties", secondaryCtorParameters[3].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, BinaryData>)), secondaryCtorParameters[3].Type);
|
||||
// validate derived secondary constructor
|
||||
Assert.AreEqual(6, derivedSecondaryCtorParams.Count); // all base props + 2 properties + 1 additionalRawData + additional props
|
||||
|
@ -270,7 +270,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
|
|||
Assert.AreEqual(new CSharpType(typeof(string), true), derivedSecondaryCtorParams[3].Type);
|
||||
Assert.AreEqual("additionalProperties", derivedSecondaryCtorParams[4].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, string>)), derivedSecondaryCtorParams[4].Type);
|
||||
Assert.AreEqual("serializedAdditionalRawData", derivedSecondaryCtorParams[5].Name);
|
||||
Assert.AreEqual("additionalBinaryDataProperties", derivedSecondaryCtorParams[5].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, BinaryData>)), derivedSecondaryCtorParams[5].Type);
|
||||
}
|
||||
|
||||
|
@ -296,14 +296,14 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
|
|||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, long>)), additionalPropertiesParam?.Type);
|
||||
var rawDataParam = constructorSignature?.Parameters[1];
|
||||
Assert.IsNotNull(rawDataParam);
|
||||
Assert.AreEqual("serializedAdditionalRawData", rawDataParam?.Name);
|
||||
Assert.AreEqual("additionalBinaryDataProperties", rawDataParam?.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(1, constructorSignature?.Parameters.Count);
|
||||
var param = constructorSignature?.Parameters[0];
|
||||
Assert.IsNotNull(param);
|
||||
Assert.AreEqual("serializedAdditionalRawData", param?.Name);
|
||||
Assert.AreEqual("additionalBinaryDataProperties", param?.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,58 +350,137 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
|
|||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBuildFields(bool containsUnknownAdditionalProp)
|
||||
public void TestBuildFields(bool containsMixedAdditionalProperties)
|
||||
{
|
||||
InputType? additionalProperties = containsUnknownAdditionalProp ? InputPrimitiveType.Any : null;
|
||||
InputType? additionalProperties = containsMixedAdditionalProperties
|
||||
? InputFactory.Union([InputPrimitiveType.Float64, InputPrimitiveType.Int64, InputPrimitiveType.String])
|
||||
: null;
|
||||
var inputModel = InputFactory.Model("TestModel", properties: [], additionalProperties: additionalProperties);
|
||||
var modelTypeProvider = new ModelProvider(inputModel);
|
||||
var fields = modelTypeProvider.Fields;
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(fields);
|
||||
if (containsUnknownAdditionalProp)
|
||||
|
||||
if (containsMixedAdditionalProperties)
|
||||
{
|
||||
Assert.AreEqual(0, fields.Count);
|
||||
Assert.AreEqual(4, fields.Count);
|
||||
Assert.AreEqual("_additionalBinaryDataProperties", fields[0].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, BinaryData>)), fields[0].Type);
|
||||
Assert.AreEqual("_additionalDoubleProperties", fields[1].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, double>)), fields[1].Type);
|
||||
Assert.AreEqual("_additionalInt64Properties", fields[2].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, long>)), fields[2].Type);
|
||||
Assert.AreEqual("_additionalStringProperties", fields[3].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, string>)), fields[3].Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(1, fields.Count);
|
||||
Assert.AreEqual("_serializedAdditionalRawData", fields[0].Name);
|
||||
var type = fields[0].Type;
|
||||
Assert.IsTrue(type.IsCollection);
|
||||
Assert.AreEqual("_additionalBinaryDataProperties", fields[0].Name);
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, BinaryData>)), fields[0].Type);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(BuildAdditionalPropertiesTestCases))]
|
||||
public void TestBuildAdditionalProperties(InputType additionalProperties, bool isUnverifiableType)
|
||||
public void TestBuildAdditionalProperties(
|
||||
InputModelType inputModel,
|
||||
bool isUnverifiableType,
|
||||
int expectedPropertyCount)
|
||||
{
|
||||
var inputModel = InputFactory.Model("TestModel", properties: [], additionalProperties: additionalProperties);
|
||||
var modelTypeProvider = new ModelProvider(inputModel);
|
||||
|
||||
var additionalPropertiesProp = modelTypeProvider.Properties.FirstOrDefault(f => f.Name == "AdditionalProperties");
|
||||
Assert.IsNotNull(additionalPropertiesProp);
|
||||
var additionalPropertiesProps = modelTypeProvider.Properties.Where(f => f.Name.StartsWith("Additional")).ToList();
|
||||
Assert.AreEqual(expectedPropertyCount, additionalPropertiesProps.Count);
|
||||
|
||||
var additionalPropertiesType = additionalPropertiesProp!.Type;
|
||||
Assert.IsTrue(additionalPropertiesType.IsDictionary);
|
||||
|
||||
if (isUnverifiableType)
|
||||
foreach (var additionalPropertiesProp in additionalPropertiesProps)
|
||||
{
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, BinaryData>)), additionalPropertiesType);
|
||||
var additionalPropertiesType = additionalPropertiesProp!.Type;
|
||||
Assert.IsTrue(additionalPropertiesType.IsDictionary);
|
||||
|
||||
if (isUnverifiableType)
|
||||
{
|
||||
Assert.AreEqual(new CSharpType(typeof(IDictionary<string, BinaryData>)), additionalPropertiesType);
|
||||
}
|
||||
if (!inputModel.Usage.HasFlag(InputModelTypeUsage.Input))
|
||||
{
|
||||
Assert.IsTrue(additionalPropertiesType.IsReadOnlyDictionary);
|
||||
// validate the assignment
|
||||
var body = additionalPropertiesProp.Body as ExpressionPropertyBody;
|
||||
Assert.NotNull(body);
|
||||
Assert.IsTrue(body!.Getter.ToDisplayString().StartsWith(
|
||||
"new global::System.Collections.ObjectModel.ReadOnlyDictionary<string,"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAdditionalPropertiesPropertyNamesAndAccessors()
|
||||
{
|
||||
// model with multiple additional properties
|
||||
var inputModelWithMultipleAp = InputFactory.Model(
|
||||
"TestModel",
|
||||
properties: [],
|
||||
additionalProperties: InputFactory.Union([InputPrimitiveType.String, InputPrimitiveType.Int32]));
|
||||
var modelWithMultipleAp = new ModelProvider(inputModelWithMultipleAp);
|
||||
var additionalProperties1 = modelWithMultipleAp.Properties.Where(f => f.Name.StartsWith("Additional")).ToList();
|
||||
|
||||
Assert.AreEqual(2, additionalProperties1.Count);
|
||||
// validate modifiers
|
||||
Assert.IsTrue(additionalProperties1[0]!.Modifiers.HasFlag(MethodSignatureModifiers.Public));
|
||||
Assert.IsTrue(additionalProperties1[1]!.Modifiers.HasFlag(MethodSignatureModifiers.Public));
|
||||
// validate names
|
||||
Assert.AreEqual("AdditionalProperties", additionalProperties1[0].Name);
|
||||
Assert.AreEqual("AdditionalInt32Properties", additionalProperties1[1].Name);
|
||||
// validate getters
|
||||
var stringAdditionalPropertyGetter = additionalProperties1[0]!.Body as ExpressionPropertyBody;
|
||||
Assert.NotNull(stringAdditionalPropertyGetter);
|
||||
Assert.IsTrue(stringAdditionalPropertyGetter!.Getter.ToDisplayString().Equals("_additionalStringProperties"));
|
||||
var int32AdditionalPropertyGetter = additionalProperties1[1]!.Body as ExpressionPropertyBody;
|
||||
Assert.NotNull(int32AdditionalPropertyGetter);
|
||||
Assert.IsTrue(int32AdditionalPropertyGetter!.Getter.ToDisplayString().Equals("_additionalInt32Properties"));
|
||||
|
||||
// model with single additional property
|
||||
var inputModelWithSingleAp = InputFactory.Model(
|
||||
"TestModel",
|
||||
properties: [],
|
||||
additionalProperties: InputPrimitiveType.String);
|
||||
var modelWithSingleAp = new ModelProvider(inputModelWithSingleAp);
|
||||
var additionalProperties2 = modelWithSingleAp.Properties.Where(f => f.Name.StartsWith("Additional")).ToList();
|
||||
|
||||
Assert.AreEqual(1, additionalProperties2.Count);
|
||||
// validate modifiers
|
||||
Assert.IsTrue(additionalProperties2[0]!.Modifiers.HasFlag(MethodSignatureModifiers.Public));
|
||||
// validate names
|
||||
Assert.AreEqual("AdditionalProperties", additionalProperties2[0].Name);
|
||||
// validate getters
|
||||
var singleAdditionalPropertyGetter = additionalProperties2[0]!.Body as ExpressionPropertyBody;
|
||||
Assert.NotNull(singleAdditionalPropertyGetter);
|
||||
Assert.IsTrue(singleAdditionalPropertyGetter!.Getter.ToDisplayString().Equals("_additionalStringProperties"));
|
||||
|
||||
// model with no additional properties
|
||||
var inputModelWithNoAp = InputFactory.Model("TestModel", properties: []);
|
||||
var modelWithNoAp = new ModelProvider(inputModelWithNoAp);
|
||||
var additionalProperties3 = modelWithNoAp.Properties.Where(f => f.Name.StartsWith("Additional")).ToList();
|
||||
Assert.AreEqual(0, additionalProperties3.Count);
|
||||
|
||||
}
|
||||
|
||||
public static IEnumerable<TestCaseData> BuildAdditionalPropertiesTestCases
|
||||
{
|
||||
get
|
||||
{
|
||||
// verifiable type
|
||||
yield return new TestCaseData(InputPrimitiveType.String, false);
|
||||
yield return new TestCaseData(InputFactory.Array(InputPrimitiveType.String), false);
|
||||
yield return new TestCaseData(InputFactory.Dictionary(InputPrimitiveType.String), false);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputPrimitiveType.String), false, 1);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputFactory.Array(InputPrimitiveType.String)), false, 1);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputFactory.Dictionary(InputPrimitiveType.String)), false, 1);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputFactory.Union([InputPrimitiveType.String, InputPrimitiveType.Int32])), false, 2);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputFactory.Union([InputPrimitiveType.String, InputPrimitiveType.Int32, InputFactory.Model("foo")])), false, 3);
|
||||
// output model
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", usage: InputModelTypeUsage.Output, properties: [], additionalProperties: InputPrimitiveType.String), false, 1);
|
||||
|
||||
// non-verifiable type
|
||||
yield return new TestCaseData(InputPrimitiveType.Any, true);
|
||||
yield return new TestCaseData(InputFactory.Model("foo"), true);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputPrimitiveType.Any), true, 1);
|
||||
yield return new TestCaseData(InputFactory.Model("TestModel", properties: [], additionalProperties: InputFactory.Model("foo")), true, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Sample.Models
|
|||
public partial class TestModel
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> _serializedAdditionalRawData;
|
||||
private protected global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
/// <summary> Initializes a new instance of <see cref="global::Sample.Models.TestModel"/>. </summary>
|
||||
/// <param name="requiredString"> Description for requiredString. </param>
|
||||
|
@ -26,11 +26,11 @@ namespace Sample.Models
|
|||
RequiredInt = requiredInt;
|
||||
}
|
||||
|
||||
internal TestModel(string requiredString, int requiredInt, global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> serializedAdditionalRawData)
|
||||
internal TestModel(string requiredString, int requiredInt, global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
RequiredString = requiredString;
|
||||
RequiredInt = requiredInt;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> Description for requiredString. </summary>
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Sample.Models
|
|||
public readonly partial struct TestModel
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> _serializedAdditionalRawData;
|
||||
private protected global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
/// <summary> Initializes a new instance of <see cref="global::Sample.Models.TestModel"/>. </summary>
|
||||
/// <param name="requiredString"> Description for requiredString. </param>
|
||||
|
@ -26,11 +26,11 @@ namespace Sample.Models
|
|||
RequiredInt = requiredInt;
|
||||
}
|
||||
|
||||
internal TestModel(string requiredString, int requiredInt, global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> serializedAdditionalRawData)
|
||||
internal TestModel(string requiredString, int requiredInt, global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
RequiredString = requiredString;
|
||||
RequiredInt = requiredInt;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> Description for requiredString. </summary>
|
||||
|
|
|
@ -186,6 +186,11 @@ namespace Microsoft.Generator.CSharp.Tests.Common
|
|||
return new InputDictionaryType("dictionary", keyType ?? InputPrimitiveType.String, valueType);
|
||||
}
|
||||
|
||||
public static InputType Union(IList<InputType> types)
|
||||
{
|
||||
return new InputUnionType("union", [.. types]);
|
||||
}
|
||||
|
||||
public static InputOperation Operation(
|
||||
string name,
|
||||
string access = "public",
|
||||
|
|
|
@ -198,7 +198,7 @@ namespace Microsoft.Generator.CSharp.Tests.Common
|
|||
{
|
||||
modelType = modelType.BaseType!;
|
||||
}
|
||||
var propertyInfo = modelType.GetField("_serializedAdditionalRawData", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
var propertyInfo = modelType.GetField("_additionalBinaryDataProperties", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
return propertyInfo?.GetValue(model) as IDictionary<string, BinaryData> ?? throw new InvalidOperationException($"unable to get raw data from {model.GetType().Name}");
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace _Type.Model.Inheritance.EnumDiscriminator.Models
|
|||
{
|
||||
public Cobra(int length) : base(SnakeKind.Cobra, length) => throw null;
|
||||
|
||||
internal Cobra(int length, IDictionary<string, BinaryData> serializedAdditionalRawData) : base(SnakeKind.Cobra, length, serializedAdditionalRawData) => throw null;
|
||||
internal Cobra(int length, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base(SnakeKind.Cobra, length, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace _Type.Model.Inheritance.EnumDiscriminator.Models
|
|||
{
|
||||
private protected Dog(DogKind kind, int weight) => throw null;
|
||||
|
||||
internal Dog(DogKind kind, int weight, IDictionary<string, BinaryData> serializedAdditionalRawData) => throw null;
|
||||
internal Dog(DogKind kind, int weight, IDictionary<string, BinaryData> additionalBinaryDataProperties) => throw null;
|
||||
|
||||
internal DogKind Kind
|
||||
{
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace _Type.Model.Inheritance.EnumDiscriminator.Models
|
|||
{
|
||||
public Golden(int weight) : base(DogKind.Golden, weight) => throw null;
|
||||
|
||||
internal Golden(int weight, IDictionary<string, BinaryData> serializedAdditionalRawData) : base(DogKind.Golden, weight, serializedAdditionalRawData) => throw null;
|
||||
internal Golden(int weight, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base(DogKind.Golden, weight, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace _Type.Model.Inheritance.EnumDiscriminator.Models
|
|||
{
|
||||
private protected Snake(SnakeKind kind, int length) => throw null;
|
||||
|
||||
internal Snake(SnakeKind kind, int length, IDictionary<string, BinaryData> serializedAdditionalRawData) => throw null;
|
||||
internal Snake(SnakeKind kind, int length, IDictionary<string, BinaryData> additionalBinaryDataProperties) => throw null;
|
||||
|
||||
internal SnakeKind Kind
|
||||
{
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace _Type.Model.Inheritance.EnumDiscriminator.Models
|
|||
{
|
||||
internal partial class UnknownDog : Dog
|
||||
{
|
||||
internal UnknownDog(DogKind kind, int weight, IDictionary<string, BinaryData> serializedAdditionalRawData) : base(kind != default ? kind : "unknown", weight, serializedAdditionalRawData) => throw null;
|
||||
internal UnknownDog(DogKind kind, int weight, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base(kind != default ? kind : "unknown", weight, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace _Type.Model.Inheritance.EnumDiscriminator.Models
|
|||
{
|
||||
internal partial class UnknownSnake : Snake
|
||||
{
|
||||
internal UnknownSnake(SnakeKind kind, int length, IDictionary<string, BinaryData> serializedAdditionalRawData) : base(kind, length, serializedAdditionalRawData) => throw null;
|
||||
internal UnknownSnake(SnakeKind kind, int length, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base(kind, length, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
private protected Bird(string kind, int wingspan) => throw null;
|
||||
|
||||
internal Bird(string kind, int wingspan, IDictionary<string, BinaryData> serializedAdditionalRawData) => throw null;
|
||||
internal Bird(string kind, int wingspan, IDictionary<string, BinaryData> additionalBinaryDataProperties) => throw null;
|
||||
|
||||
internal string Kind
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
private protected Dinosaur(string kind, int size) => throw null;
|
||||
|
||||
internal Dinosaur(string kind, int size, IDictionary<string, BinaryData> serializedAdditionalRawData) => throw null;
|
||||
internal Dinosaur(string kind, int size, IDictionary<string, BinaryData> additionalBinaryDataProperties) => throw null;
|
||||
|
||||
internal string Kind
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
public Eagle(int wingspan) : base("eagle", wingspan) => throw null;
|
||||
|
||||
internal Eagle(IList<Bird> friends, IDictionary<string, Bird> hate, Bird partner, int wingspan, IDictionary<string, BinaryData> serializedAdditionalRawData) : base("eagle", wingspan, serializedAdditionalRawData) => throw null;
|
||||
internal Eagle(IList<Bird> friends, IDictionary<string, Bird> hate, Bird partner, int wingspan, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base("eagle", wingspan, additionalBinaryDataProperties) => throw null;
|
||||
|
||||
public IList<Bird> Friends => throw null;
|
||||
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
public Goose(int wingspan) : base("goose", wingspan) => throw null;
|
||||
|
||||
internal Goose(int wingspan, IDictionary<string, BinaryData> serializedAdditionalRawData) : base("goose", wingspan, serializedAdditionalRawData) => throw null;
|
||||
internal Goose(int wingspan, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base("goose", wingspan, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
public SeaGull(int wingspan) : base("seagull", wingspan) => throw null;
|
||||
|
||||
internal SeaGull(int wingspan, IDictionary<string, BinaryData> serializedAdditionalRawData) : base("seagull", wingspan, serializedAdditionalRawData) => throw null;
|
||||
internal SeaGull(int wingspan, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base("seagull", wingspan, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
public Sparrow(int wingspan) : base("sparrow", wingspan) => throw null;
|
||||
|
||||
internal Sparrow(int wingspan, IDictionary<string, BinaryData> serializedAdditionalRawData) : base("sparrow", wingspan, serializedAdditionalRawData) => throw null;
|
||||
internal Sparrow(int wingspan, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base("sparrow", wingspan, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
internal TRex(int size) : base("t-rex", size) => throw null;
|
||||
|
||||
internal TRex(int size, IDictionary<string, BinaryData> serializedAdditionalRawData) : base("t-rex", size, serializedAdditionalRawData) => throw null;
|
||||
internal TRex(int size, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base("t-rex", size, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
internal partial class UnknownBird : Bird
|
||||
{
|
||||
internal UnknownBird(string kind, int wingspan, IDictionary<string, BinaryData> serializedAdditionalRawData) : base(kind ?? "unknown", wingspan, serializedAdditionalRawData) => throw null;
|
||||
internal UnknownBird(string kind, int wingspan, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base(kind ?? "unknown", wingspan, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace _Type.Model.Inheritance.SingleDiscriminator.Models
|
|||
{
|
||||
internal partial class UnknownDinosaur : Dinosaur
|
||||
{
|
||||
internal UnknownDinosaur(string kind, int size, IDictionary<string, BinaryData> serializedAdditionalRawData) : base(kind ?? "unknown", size, serializedAdditionalRawData) => throw null;
|
||||
internal UnknownDinosaur(string kind, int size, IDictionary<string, BinaryData> additionalBinaryDataProperties) : base(kind ?? "unknown", size, additionalBinaryDataProperties) => throw null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,9 +106,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
{
|
||||
writer.WriteNull("requiredNullableList"u8);
|
||||
}
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -157,7 +157,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
string requiredBadDescription = default;
|
||||
IList<int> optionalNullableList = default;
|
||||
IList<int> requiredNullableList = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("name"u8))
|
||||
|
@ -266,7 +266,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new AnonymousBodyRequest(
|
||||
|
@ -283,7 +283,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
requiredBadDescription,
|
||||
optionalNullableList ?? new ChangeTrackingList<int>(),
|
||||
requiredNullableList,
|
||||
serializedAdditionalRawData);
|
||||
additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<AnonymousBodyRequest>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
internal partial class AnonymousBodyRequest
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
internal AnonymousBodyRequest(string name, BinaryData requiredUnion, string requiredBadDescription, IEnumerable<int> requiredNullableList)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
RequiredNullableList = requiredNullableList?.ToList();
|
||||
}
|
||||
|
||||
internal AnonymousBodyRequest(string name, BinaryData requiredUnion, AnonymousBodyRequestRequiredLiteralString requiredLiteralString, AnonymousBodyRequestRequiredLiteralInt requiredLiteralInt, AnonymousBodyRequestRequiredLiteralFloat requiredLiteralFloat, bool requiredLiteralBool, AnonymousBodyRequestOptionalLiteralString? optionalLiteralString, AnonymousBodyRequestOptionalLiteralInt? optionalLiteralInt, AnonymousBodyRequestOptionalLiteralFloat? optionalLiteralFloat, bool? optionalLiteralBool, string requiredBadDescription, IList<int> optionalNullableList, IList<int> requiredNullableList, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal AnonymousBodyRequest(string name, BinaryData requiredUnion, AnonymousBodyRequestRequiredLiteralString requiredLiteralString, AnonymousBodyRequestRequiredLiteralInt requiredLiteralInt, AnonymousBodyRequestRequiredLiteralFloat requiredLiteralFloat, bool requiredLiteralBool, AnonymousBodyRequestOptionalLiteralString? optionalLiteralString, AnonymousBodyRequestOptionalLiteralInt? optionalLiteralInt, AnonymousBodyRequestOptionalLiteralFloat? optionalLiteralFloat, bool? optionalLiteralBool, string requiredBadDescription, IList<int> optionalNullableList, IList<int> requiredNullableList, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
Name = name;
|
||||
RequiredUnion = requiredUnion;
|
||||
|
@ -40,7 +40,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
RequiredBadDescription = requiredBadDescription;
|
||||
OptionalNullableList = optionalNullableList;
|
||||
RequiredNullableList = requiredNullableList;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> name of the Thing. </summary>
|
||||
|
|
|
@ -36,9 +36,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
writer.WritePropertyName("name"u8);
|
||||
writer.WriteStringValue(Name);
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -75,7 +75,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
return null;
|
||||
}
|
||||
string name = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("name"u8))
|
||||
|
@ -85,10 +85,10 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new Friend(name, serializedAdditionalRawData);
|
||||
return new Friend(name, additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<Friend>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -11,17 +11,17 @@ namespace UnbrandedTypeSpec.Models
|
|||
public partial class Friend
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
internal Friend(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal Friend(string name, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal Friend(string name, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
Name = name;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> name of the NotFriend. </summary>
|
||||
|
|
|
@ -36,9 +36,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
writer.WritePropertyName("name"u8);
|
||||
writer.WriteStringValue(Name);
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -75,7 +75,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
return null;
|
||||
}
|
||||
string name = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("name"u8))
|
||||
|
@ -85,10 +85,10 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new FriendlyModelRequest(name, serializedAdditionalRawData);
|
||||
return new FriendlyModelRequest(name, additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<FriendlyModelRequest>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -11,17 +11,17 @@ namespace UnbrandedTypeSpec.Models
|
|||
internal partial class FriendlyModelRequest
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
internal FriendlyModelRequest(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal FriendlyModelRequest(string name, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal FriendlyModelRequest(string name, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
Name = name;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> name of the NotFriend. </summary>
|
||||
|
|
|
@ -61,9 +61,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
{
|
||||
writer.WriteNull("requiredFixedEnum"u8);
|
||||
}
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -102,7 +102,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
int? requiredNullablePrimitive = default;
|
||||
StringExtensibleEnum? requiredExtensibleEnum = default;
|
||||
StringFixedEnum? requiredFixedEnum = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("requiredNullablePrimitive"u8))
|
||||
|
@ -137,10 +137,10 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new ModelWithRequiredNullableProperties(requiredNullablePrimitive, requiredExtensibleEnum, requiredFixedEnum, serializedAdditionalRawData);
|
||||
return new ModelWithRequiredNullableProperties(requiredNullablePrimitive, requiredExtensibleEnum, requiredFixedEnum, additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<ModelWithRequiredNullableProperties>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
public partial class ModelWithRequiredNullableProperties
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
/// <summary> Initializes a new instance of <see cref="ModelWithRequiredNullableProperties"/>. </summary>
|
||||
/// <param name="requiredNullablePrimitive"> required nullable primitive type. </param>
|
||||
|
@ -24,12 +24,12 @@ namespace UnbrandedTypeSpec.Models
|
|||
RequiredFixedEnum = requiredFixedEnum;
|
||||
}
|
||||
|
||||
internal ModelWithRequiredNullableProperties(int? requiredNullablePrimitive, StringExtensibleEnum? requiredExtensibleEnum, StringFixedEnum? requiredFixedEnum, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal ModelWithRequiredNullableProperties(int? requiredNullablePrimitive, StringExtensibleEnum? requiredExtensibleEnum, StringFixedEnum? requiredFixedEnum, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
RequiredNullablePrimitive = requiredNullablePrimitive;
|
||||
RequiredExtensibleEnum = requiredExtensibleEnum;
|
||||
RequiredFixedEnum = requiredFixedEnum;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> required nullable primitive type. </summary>
|
||||
|
|
|
@ -36,9 +36,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
writer.WritePropertyName("name"u8);
|
||||
writer.WriteStringValue(Name);
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -75,7 +75,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
return null;
|
||||
}
|
||||
string name = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("name"u8))
|
||||
|
@ -85,10 +85,10 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new ProjectedModel(name, serializedAdditionalRawData);
|
||||
return new ProjectedModel(name, additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<ProjectedModel>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -11,17 +11,17 @@ namespace UnbrandedTypeSpec.Models
|
|||
public partial class ProjectedModel
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
internal ProjectedModel(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal ProjectedModel(string name, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal ProjectedModel(string name, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
Name = name;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> name of the ModelWithProjectedName. </summary>
|
||||
|
|
|
@ -36,9 +36,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
writer.WritePropertyName("name"u8);
|
||||
writer.WriteStringValue(Name);
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -75,7 +75,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
return null;
|
||||
}
|
||||
string name = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("name"u8))
|
||||
|
@ -85,10 +85,10 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new ProjectedNameModelRequest(name, serializedAdditionalRawData);
|
||||
return new ProjectedNameModelRequest(name, additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<ProjectedNameModelRequest>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -11,17 +11,17 @@ namespace UnbrandedTypeSpec.Models
|
|||
internal partial class ProjectedNameModelRequest
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
internal ProjectedNameModelRequest(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal ProjectedNameModelRequest(string name, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal ProjectedNameModelRequest(string name, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
Name = name;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> name of the ModelWithProjectedName. </summary>
|
||||
|
|
|
@ -30,9 +30,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
{
|
||||
throw new FormatException($"The model {nameof(ReturnsAnonymousModelResponse)} does not support writing '{format}' format.");
|
||||
}
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -68,15 +68,15 @@ namespace UnbrandedTypeSpec.Models
|
|||
{
|
||||
return null;
|
||||
}
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new ReturnsAnonymousModelResponse(serializedAdditionalRawData);
|
||||
return new ReturnsAnonymousModelResponse(additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<ReturnsAnonymousModelResponse>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -11,15 +11,15 @@ namespace UnbrandedTypeSpec.Models
|
|||
public partial class ReturnsAnonymousModelResponse
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
internal ReturnsAnonymousModelResponse()
|
||||
{
|
||||
}
|
||||
|
||||
internal ReturnsAnonymousModelResponse(IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal ReturnsAnonymousModelResponse(IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,9 +244,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
writer.WriteObjectValue(ModelWithRequiredNullable, options);
|
||||
writer.WritePropertyName("requiredBytes"u8);
|
||||
writer.WriteBase64StringValue(RequiredBytes.ToArray(), "D");
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -306,7 +306,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
IReadOnlyDictionary<string, BinaryData> readOnlyOptionalRecordUnknown = default;
|
||||
ModelWithRequiredNullableProperties modelWithRequiredNullable = default;
|
||||
BinaryData requiredBytes = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("requiredString"u8))
|
||||
|
@ -573,7 +573,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new RoundTripModel(
|
||||
|
@ -601,7 +601,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
readOnlyOptionalRecordUnknown ?? new ChangeTrackingDictionary<string, BinaryData>(),
|
||||
modelWithRequiredNullable,
|
||||
requiredBytes,
|
||||
serializedAdditionalRawData);
|
||||
additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<RoundTripModel>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
public partial class RoundTripModel
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
/// <summary> Initializes a new instance of <see cref="RoundTripModel"/>. </summary>
|
||||
/// <param name="requiredString"> Required string, illustrating a reference type property. </param>
|
||||
|
@ -56,7 +56,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
RequiredBytes = requiredBytes;
|
||||
}
|
||||
|
||||
internal RoundTripModel(string requiredString, int requiredInt, IList<StringFixedEnum> requiredCollection, IDictionary<string, StringExtensibleEnum> requiredDictionary, Thing requiredModel, IntExtensibleEnum? intExtensibleEnum, IList<IntExtensibleEnum> intExtensibleEnumCollection, FloatExtensibleEnum? floatExtensibleEnum, FloatExtensibleEnumWithIntValue? floatExtensibleEnumWithIntValue, IList<FloatExtensibleEnum> floatExtensibleEnumCollection, FloatFixedEnum? floatFixedEnum, FloatFixedEnumWithIntValue? floatFixedEnumWithIntValue, IList<FloatFixedEnum> floatFixedEnumCollection, IntFixedEnum? intFixedEnum, IList<IntFixedEnum> intFixedEnumCollection, StringFixedEnum? stringFixedEnum, BinaryData requiredUnknown, BinaryData optionalUnknown, IDictionary<string, BinaryData> requiredRecordUnknown, IDictionary<string, BinaryData> optionalRecordUnknown, IReadOnlyDictionary<string, BinaryData> readOnlyRequiredRecordUnknown, IReadOnlyDictionary<string, BinaryData> readOnlyOptionalRecordUnknown, ModelWithRequiredNullableProperties modelWithRequiredNullable, BinaryData requiredBytes, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal RoundTripModel(string requiredString, int requiredInt, IList<StringFixedEnum> requiredCollection, IDictionary<string, StringExtensibleEnum> requiredDictionary, Thing requiredModel, IntExtensibleEnum? intExtensibleEnum, IList<IntExtensibleEnum> intExtensibleEnumCollection, FloatExtensibleEnum? floatExtensibleEnum, FloatExtensibleEnumWithIntValue? floatExtensibleEnumWithIntValue, IList<FloatExtensibleEnum> floatExtensibleEnumCollection, FloatFixedEnum? floatFixedEnum, FloatFixedEnumWithIntValue? floatFixedEnumWithIntValue, IList<FloatFixedEnum> floatFixedEnumCollection, IntFixedEnum? intFixedEnum, IList<IntFixedEnum> intFixedEnumCollection, StringFixedEnum? stringFixedEnum, BinaryData requiredUnknown, BinaryData optionalUnknown, IDictionary<string, BinaryData> requiredRecordUnknown, IDictionary<string, BinaryData> optionalRecordUnknown, IReadOnlyDictionary<string, BinaryData> readOnlyRequiredRecordUnknown, IReadOnlyDictionary<string, BinaryData> readOnlyOptionalRecordUnknown, ModelWithRequiredNullableProperties modelWithRequiredNullable, BinaryData requiredBytes, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
RequiredString = requiredString;
|
||||
RequiredInt = requiredInt;
|
||||
|
@ -82,7 +82,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
ReadOnlyOptionalRecordUnknown = readOnlyOptionalRecordUnknown;
|
||||
ModelWithRequiredNullable = modelWithRequiredNullable;
|
||||
RequiredBytes = requiredBytes;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> Required string, illustrating a reference type property. </summary>
|
||||
|
|
|
@ -106,9 +106,9 @@ namespace UnbrandedTypeSpec.Models
|
|||
{
|
||||
writer.WriteNull("requiredNullableList"u8);
|
||||
}
|
||||
if (options.Format != "W" && _serializedAdditionalRawData != null)
|
||||
if (options.Format != "W" && _additionalBinaryDataProperties != null)
|
||||
{
|
||||
foreach (var item in _serializedAdditionalRawData)
|
||||
foreach (var item in _additionalBinaryDataProperties)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -157,7 +157,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
string requiredBadDescription = default;
|
||||
IList<int> optionalNullableList = default;
|
||||
IList<int> requiredNullableList = default;
|
||||
IDictionary<string, BinaryData> serializedAdditionalRawData = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
|
||||
foreach (var prop in element.EnumerateObject())
|
||||
{
|
||||
if (prop.NameEquals("name"u8))
|
||||
|
@ -266,7 +266,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
}
|
||||
if (options.Format != "W")
|
||||
{
|
||||
serializedAdditionalRawData.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
|
||||
}
|
||||
}
|
||||
return new Thing(
|
||||
|
@ -283,7 +283,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
requiredBadDescription,
|
||||
optionalNullableList ?? new ChangeTrackingList<int>(),
|
||||
requiredNullableList,
|
||||
serializedAdditionalRawData);
|
||||
additionalBinaryDataProperties);
|
||||
}
|
||||
|
||||
BinaryData IPersistableModel<Thing>.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
public partial class Thing
|
||||
{
|
||||
/// <summary> Keeps track of any properties unknown to the library. </summary>
|
||||
private protected IDictionary<string, BinaryData> _serializedAdditionalRawData;
|
||||
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
|
||||
|
||||
/// <summary> Initializes a new instance of <see cref="Thing"/>. </summary>
|
||||
/// <param name="name"> name of the Thing. </param>
|
||||
|
@ -35,7 +35,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
RequiredNullableList = requiredNullableList?.ToList();
|
||||
}
|
||||
|
||||
internal Thing(string name, BinaryData requiredUnion, ThingRequiredLiteralString requiredLiteralString, ThingRequiredLiteralInt requiredLiteralInt, ThingRequiredLiteralFloat requiredLiteralFloat, bool requiredLiteralBool, ThingOptionalLiteralString? optionalLiteralString, ThingOptionalLiteralInt? optionalLiteralInt, ThingOptionalLiteralFloat? optionalLiteralFloat, bool? optionalLiteralBool, string requiredBadDescription, IList<int> optionalNullableList, IList<int> requiredNullableList, IDictionary<string, BinaryData> serializedAdditionalRawData)
|
||||
internal Thing(string name, BinaryData requiredUnion, ThingRequiredLiteralString requiredLiteralString, ThingRequiredLiteralInt requiredLiteralInt, ThingRequiredLiteralFloat requiredLiteralFloat, bool requiredLiteralBool, ThingOptionalLiteralString? optionalLiteralString, ThingOptionalLiteralInt? optionalLiteralInt, ThingOptionalLiteralFloat? optionalLiteralFloat, bool? optionalLiteralBool, string requiredBadDescription, IList<int> optionalNullableList, IList<int> requiredNullableList, IDictionary<string, BinaryData> additionalBinaryDataProperties)
|
||||
{
|
||||
Name = name;
|
||||
RequiredUnion = requiredUnion;
|
||||
|
@ -50,7 +50,7 @@ namespace UnbrandedTypeSpec.Models
|
|||
RequiredBadDescription = requiredBadDescription;
|
||||
OptionalNullableList = optionalNullableList;
|
||||
RequiredNullableList = requiredNullableList;
|
||||
_serializedAdditionalRawData = serializedAdditionalRawData;
|
||||
_additionalBinaryDataProperties = additionalBinaryDataProperties;
|
||||
}
|
||||
|
||||
/// <summary> name of the Thing. </summary>
|
||||
|
|
Загрузка…
Ссылка в новой задаче