-
Notifications
You must be signed in to change notification settings - Fork 347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fallback to dynamic/guessed types on unknown data #3080
base: spike/overflow-errors-on-pocos
Are you sure you want to change the base?
Fallback to dynamic/guessed types on unknown data #3080
Conversation
if(!string.IsNullOrEmpty(typeSuffix)) | ||
choiceMapping = inspector.FindClassMapping(typeSuffix); | ||
|
||
choiceMapping ??= inspector.FindClassMapping(nameof(DynamicDataType)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this could also be a DynamicPrimitive - which we could heuristically determine from the fact that there is a _
or a primitive value. But we don't know at this point, so maybe we need a method ToDynamicPrimitive() that switches to a primitive if we discover that later on.
if(choiceMapping is not null) | ||
return (choiceMapping, null); | ||
|
||
return (null, ERR.CHOICE_ELEMENT_HAS_UNKOWN_TYPE(ref r, path.GetInstancePath(), propertyMapping.Name, typeSuffix)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should never happen. In fact, the NewPocoBuilder has constants for the classmappings for DynamicDataType, and this will never be null when we use those.
@@ -236,8 +241,10 @@ private void deserializeObjectInto<T>( | |||
{ | |||
if (reader.TokenType != JsonTokenType.StartObject) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should be more flexible in our thinking: we will only call this function IF we are at an object. I know at this moment we are doing it if we are expecting an object (because of classmappings etc), but since those are just hints now, we should probably never end up in this function if we don't actually see an object on the wire.
} | ||
} | ||
|
||
private object? deserializeUnexpectedJsonValue(string propertyName, ref Utf8JsonReader reader, FhirJsonPocoDeserializerState state, bool stayOnLastToken, ClassMapping? propertySuggestion = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I think this is going to be the main workhorse, in fact we could call this straight from the main TryDeserializeResouirce and TryDeserializeObject functions - we're only expecting something, but we're no longer bound to it, so this dynamic function is really nice.
@@ -342,7 +485,7 @@ FhirJsonPocoDeserializerState state | |||
|
|||
// There might be an existing value, since FhirPrimitives may be spread out over two properties | |||
// (one with, and one without the '_') | |||
var existingValue = propertyMapping.GetValue(target); | |||
target.TryGetValue(propertyMapping.Name, out var existingValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we've moved from using IL (in GetValue) to our generated function now, which might be a bit slower.
…into feature/parsers-overflow-unknown-data # Conflicts: # src/Hl7.Fhir.Base/Serialization/BaseFhirXmlPocoDeserializer.cs
{ | ||
state.Path.EnterElement(name, null, choiceType.IsPrimitive); | ||
|
||
result = DeserializeFhirPrimitive(value as PrimitiveType, name, choiceType, null, ref reader, new(), state); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not need to be a primitive, right? Choice types can be non-primitives too,
{ | ||
state.Path.EnterElement(name, null, choiceType.IsPrimitive); | ||
|
||
result = DeserializeFhirPrimitive(value as PrimitiveType, name, choiceType, null, ref reader, new(), state); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if it is a list?
@@ -305,7 +312,7 @@ private void deserializeObjectInto<T>( | |||
|
|||
try | |||
{ | |||
state.Path.EnterElement(propMapping!.Name, !propMapping.IsCollection ? null : 0, propMapping.IsPrimitive); | |||
state.Path.EnterElement(propMapping!.Name, isEnteringJsonArray(ref reader) ? 0 : null, propMapping.IsPrimitive); | |||
deserializePropertyValueInto(target, currentPropertyName, propMapping, propValueMapping!, ref reader, objectParsingState, state); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should try to merge deserializeUnknownPropertiesInto and deserializePropertyValueInto into a single function? (it needs to do the same thing, with "the only difference" that we don't have type information)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe by making sure we always have metadata, but then the metadata for DynamicPrimitive/DynamicType/DynaimcResource etc.
Description
Targets poco branch for ease of viewing just the relevant changes, and will require the other pr.
Related issues
Closes #3050