private void CreateTypeCastPaths()

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);
                    }
                }
            }
        }