private void RetrieveNavigationPropertyPaths()

in src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs [327:427]


        private void RetrieveNavigationPropertyPaths(IEdmNavigationProperty navigationProperty, CountRestrictionsType count, ODataPath currentPath, OpenApiConvertSettings convertSettings)
        {
            Debug.Assert(navigationProperty != null);
            Debug.Assert(currentPath != null);

            // Check whether the navigation property should be part of the path
            NavigationRestrictionsType navigation = _model.GetRecord<NavigationRestrictionsType>(navigationProperty, CapabilitiesConstants.NavigationRestrictions);
            if (navigation != null && !navigation.IsNavigable)
            {
                return;
            }

            // test the expandable for the navigation property.
            bool shouldExpand = ShouldExpandNavigationProperty(navigationProperty, currentPath);

            // append a navigation property.
            currentPath.Push(new ODataNavigationPropertySegment(navigationProperty));
            AppendPath(currentPath.Clone());

            // Check whether a collection-valued navigation property should be indexed by key value(s).
            NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault();

            if (restriction == null || restriction.IndexableByKey == true)
            {
                IEdmEntityType navEntityType = navigationProperty.ToEntityType();
                var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many;
                var propertyPath = navigationProperty.GetPartnerPath()?.Path;
                var propertyPathIsEmpty = string.IsNullOrEmpty(propertyPath);

                if (targetsMany) 
                {
                    if(propertyPathIsEmpty ||
                        (count?.IsNonCountableNavigationProperty(propertyPath) ?? true))
                    {
                        // ~/entityset/{key}/collection-valued-Nav/$count
                        CreateCountPath(currentPath, convertSettings);
                    }
                }
                // ~/entityset/{key}/collection-valued-Nav/subtype
                // ~/entityset/{key}/single-valued-Nav/subtype
                CreateTypeCastPaths(currentPath, convertSettings, navigationProperty.DeclaringType, navigationProperty, targetsMany);

                if (!navigationProperty.ContainsTarget)
                {
                    // Non-Contained
                    // Single-Valued: ~/entityset/{key}/single-valued-Nav/$ref
                    // Collection-valued: ~/entityset/{key}/collection-valued-Nav/$ref?$id='{navKey}'
                    CreateRefPath(currentPath);

                    if (targetsMany)
                    {
                        // Collection-valued: DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref
                        currentPath.Push(new ODataKeySegment(navEntityType));
                        CreateRefPath(currentPath);
                        
                        CreateTypeCastPaths(currentPath, convertSettings, navigationProperty.DeclaringType, navigationProperty, false); // ~/entityset/{key}/collection-valued-Nav/{id}/subtype
                    }

                    // Get possible stream paths for the navigation entity type
                    RetrieveMediaEntityStreamPaths(navEntityType, currentPath);

                    // Get the paths for the navigation property entity type properties of type complex
                    RetrieveComplexPropertyPaths(navEntityType, currentPath, convertSettings);
                }
                else
                {
                    // append a navigation property key.
                    if (targetsMany)
                    {
                        currentPath.Push(new ODataKeySegment(navEntityType));
                        AppendPath(currentPath.Clone());

                        CreateTypeCastPaths(currentPath, convertSettings, navigationProperty.DeclaringType, navigationProperty, false); // ~/entityset/{key}/collection-valued-Nav/{id}/subtype
                    }

                    // Get possible stream paths for the navigation entity type
                    RetrieveMediaEntityStreamPaths(navEntityType, currentPath);

                    // Get the paths for the navigation property entity type properties of type complex
                    RetrieveComplexPropertyPaths(navEntityType, currentPath, convertSettings);

                    if (shouldExpand)
                    {
                        // expand to sub navigation properties
                        foreach (IEdmNavigationProperty subNavProperty in navEntityType.DeclaredNavigationProperties())
                        {
                            if (CanFilter(subNavProperty))
                            {
                                RetrieveNavigationPropertyPaths(subNavProperty, count, currentPath, convertSettings);
                            }
                        }
                    }
                }

                if (targetsMany)
                {
                    currentPath.Pop();
                }
            }
            currentPath.Pop();
        }