in src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs [488:532]
private void CreateTypeCastPaths(ODataPath currentPath, OpenApiConvertSettings convertSettings, IEdmStructuredType structuredType, IEdmVocabularyAnnotatable annotable, bool targetsMany)
{
if(currentPath == null) throw Error.ArgumentNull(nameof(currentPath));
if(convertSettings == null) throw Error.ArgumentNull(nameof(convertSettings));
if(structuredType == null) throw Error.ArgumentNull(nameof(structuredType));
if(annotable == null) throw Error.ArgumentNull(nameof(annotable));
if(!convertSettings.EnableODataTypeCast) return;
var annotedTypeNames = GetDerivedTypeConstaintTypeNames(annotable);
if(!annotedTypeNames.Any() && convertSettings.RequireDerivedTypesConstraintForODataTypeCastSegments) return; // we don't want to generate any downcast path item if there is no type cast annotation.
var annotedTypeNamesSet = new HashSet<string>(annotedTypeNames, StringComparer.OrdinalIgnoreCase);
bool filter(IEdmStructuredType x) =>
convertSettings.RequireDerivedTypesConstraintForODataTypeCastSegments && annotedTypeNames.Contains(x.FullTypeName()) ||
!convertSettings.RequireDerivedTypesConstraintForODataTypeCastSegments && (
!annotedTypeNames.Any() ||
annotedTypeNames.Contains(x.FullTypeName())
);
var targetTypes = _model
.FindAllDerivedTypes(structuredType)
.Where(x => (x.TypeKind == EdmTypeKind.Entity || x.TypeKind == EdmTypeKind.Complex) && filter(x))
.OfType<IEdmStructuredType>()
.ToArray();
foreach(var targetType in targetTypes)
{
var castPath = currentPath.Clone();
castPath.Push(new ODataTypeCastSegment(targetType));
AppendPath(castPath);
if(targetsMany)
{
CreateCountPath(castPath, convertSettings);
}
else
{
foreach(var declaredNavigationProperty in targetType.DeclaredNavigationProperties())
{
RetrieveNavigationPropertyPaths(declaredNavigationProperty, null, castPath, convertSettings);
}
}
}
}