private void WriteNamespaceDeep()

in src/Readers/Vipr.Reader.OData.v4/OdcmReader.cs [253:400]


            private void WriteNamespaceDeep(IEdmModel edmModel, string @namespace)
            {
                // Get all of the top-level elements defined in the metadata <Schema> element. This includes the EntityContainer.
                var allElements = AllElementsByNamespace(edmModel.SchemaElements, @namespace).ToList();

                // Get all of the types found in the metadata <Schema> element. No EntityContainer elements.
                var types = AllTypes(allElements).ToList();

                foreach (var enumType in AllEnumTypes(types))
                {
                    var odcmEnum = TryResolveType<OdcmEnum>(enumType.Name, enumType.Namespace);

                    odcmEnum.UnderlyingType = (OdcmPrimitiveType)ResolveType(enumType.UnderlyingType.Name, enumType.UnderlyingType.Namespace);
                    odcmEnum.IsFlags = enumType.IsFlags;
                    AddVocabularyAnnotations(odcmEnum, enumType);

                    foreach (var enumMember in enumType.Members)
                    {
                        var odcmEnumMember = new OdcmEnumMember(enumMember.Name)
                        {
                            Value = (enumMember.Value).Value
                        };

                        AddVocabularyAnnotations(odcmEnumMember, enumMember);
                        odcmEnum.Members.Add(odcmEnumMember);
                    }
                }

                foreach (var typeDefinition in AllTypeDefinitions(types))
                {
                    var odcmTypeDefinition = TryResolveType<OdcmTypeDefinition>(typeDefinition.Name, typeDefinition.Namespace);

                    // Type definitions should only support primitives as their base types [http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part3-csdl.html]
                    var baseType = ResolveType(typeDefinition.UnderlyingType.Name, typeDefinition.UnderlyingType.Namespace) as OdcmPrimitiveType;
                    if (baseType == null)
                    {
                        throw new InvalidOperationException("Type definitions should only accept primitive type as their base type.");
                    }

                    odcmTypeDefinition.BaseType = baseType;
                    AddVocabularyAnnotations(odcmTypeDefinition, typeDefinition);
                }

                foreach (var complexType in AllComplexTypes(types))
                {
                    var odcmClass = TryResolveType<OdcmClass>(complexType.Name, complexType.Namespace);

                    odcmClass.IsAbstract = complexType.IsAbstract;
                    odcmClass.IsOpen = complexType.IsOpen;
                    AddVocabularyAnnotations(odcmClass, complexType);

                    ResolveBaseClass(odcmClass, complexType);

                    foreach (var property in complexType.DeclaredProperties)
                    {
                        WriteProperty(odcmClass, property);
                    }
                }

                var entityTypes = AllEntityTypes(types).ToList();

                // First make a pass through entity types to establish their hierarchy;
                // this is useful for cases when base entity type is defined after derived one
                foreach (var entityType in entityTypes)
                {
                    var odcmClass = TryResolveType<OdcmEntityClass>(entityType.Name, entityType.Namespace);

                    ResolveBaseClass(odcmClass, entityType);
                }

                foreach (var entityType in entityTypes)
                {
                    var odcmClass = TryResolveType<OdcmEntityClass>(entityType.Name, entityType.Namespace);

                    odcmClass.IsAbstract = entityType.IsAbstract;
                    odcmClass.IsOpen = entityType.IsOpen;

                    // Add all of the structural and navigation properties to the EntityType, which is an OdcmClass.
                    // Capability annotations are not yet set on the OdcmClass.Properties[x].Projection.
                    foreach (var property in entityType.DeclaredProperties)
                    {
                        WriteProperty(odcmClass, property);
                    }

                    foreach (IEdmStructuralProperty keyProperty in entityType.Key())
                    {
                        OdcmProperty property;
                        if (!odcmClass.TryFindProperty(keyProperty.Name, out property))
                        {
                            throw new InvalidOperationException();
                        }

                        if (property.IsNullable)
                        {
                            //TODO: need to create a warning...
                        }

                        odcmClass.Key.Add(property);
                    }

                    // Add the capability annotations to OdcmClass.Properties[x].Projection
                    AddVocabularyAnnotations(odcmClass, entityType);
                }

                foreach (var entityContainer in AllEntityContainers(allElements))
                {
                    var odcmClass = TryResolveType<OdcmClass>(entityContainer.Name, entityContainer.Namespace);

                    odcmClass.Projection = new OdcmProjection
                    {
                        Type = odcmClass
                    };

                    try
                    {
                        _propertyCapabilitiesCache.Add(odcmClass, new List<OdcmCapability>());
                    }
                    catch (InvalidOperationException e)
                    {
                        Logger.Warn("Failed to add property to cache", e);
                    }
                    AddVocabularyAnnotations(odcmClass, entityContainer);

                    var entitySets = ContainerElementsByKind<IEdmEntitySet>(entityContainer, EdmContainerElementKind.EntitySet);
                    foreach (var entitySet in entitySets)
                    {
                        WriteProperty(odcmClass, entitySet);
                    }

                    var singletons = ContainerElementsByKind<IEdmSingleton>(entityContainer, EdmContainerElementKind.Singleton);
                    foreach (var singleton in singletons)
                    {
                        WriteProperty(odcmClass, singleton);
                    }

                    var actionImports = ContainerElementsByKind<IEdmActionImport>(entityContainer, EdmContainerElementKind.ActionImport);
                    foreach (var actionImport in actionImports)
                    {
                        WriteMethodImport(odcmClass, actionImport.Action, actionImport);
                    }

                    var functionImports = ContainerElementsByKind<IEdmFunctionImport>(entityContainer, EdmContainerElementKind.FunctionImport);
                    foreach (var functionImport in functionImports)
                    {
                        WriteMethodImport(odcmClass, functionImport.Function, functionImport);
                    }
                }
            }