private void BuildContentTypes()

in src/Editor/Core/Impl/ContentType/ContentTypeRegistryServiceImpl.cs [88:182]


        private void BuildContentTypes()
        {
            var oldMaps = Volatile.Read(ref this.maps);
            if (oldMaps == null)
            {
                var nameToContentTypeBuilder = MapCollection.Empty.NameToContentTypeMap.ToBuilder();
                var mimeTypeToContentTypeBuilder = MapCollection.Empty.MimeTypeToContentTypeMap.ToBuilder();

                // Add the singleton Unknown content type to the dictionary
                nameToContentTypeBuilder.Add(ContentTypeRegistryImpl.UnknownContentTypeName, ContentTypeRegistryImpl.UnknownContentTypeImpl);


                // For each content type provision, create an IContentType.
                foreach (Lazy<ContentTypeDefinition, IContentTypeDefinitionMetadata> contentTypeDefinition in ContentTypeDefinitions)
                {
                    AddContentTypeFromMetadata(contentTypeDefinition.Metadata.Name,
                                               contentTypeDefinition.Metadata.MimeType,
                                               contentTypeDefinition.Metadata.BaseDefinition, nameToContentTypeBuilder, mimeTypeToContentTypeBuilder);
                }

                // Now consider the external sources. This allows us to consider legacy content types together with MEF-defined
                // content types.
                foreach (IContentTypeDefinitionSource source in this.ExternalSources)
                {
                    if (source.Definitions != null)
                    {
                        foreach (IContentTypeDefinition metadata in source.Definitions)
                        {
                            AddContentTypeFromMetadata(metadata.Name,
                                                       /* mimeType*/ null,
                                                       metadata.BaseDefinitions, nameToContentTypeBuilder, mimeTypeToContentTypeBuilder);
                        }
                    }
                }

                List<ContentTypeImpl> allTypes = new List<ContentTypeImpl>(nameToContentTypeBuilder.Count);
                allTypes.AddRange(nameToContentTypeBuilder.Values);
                foreach (var type in allTypes)
                {
                    type.ProcessBaseTypes(nameToContentTypeBuilder, mimeTypeToContentTypeBuilder);
                }

#if DEBUG
                foreach (var type in nameToContentTypeBuilder.Values)
                {
                    Debug.Assert(type.IsProcessed);
                }
#endif

                foreach (var type in nameToContentTypeBuilder.Values)
                {
                    type.CheckForCycle(breakCycle: true);
                }

                var fileExtensionToContentTypeMapBuilder = MapCollection.Empty.FileExtensionToContentTypeMap.ToBuilder();
                var fileNameToContentTypeMapBuilder = MapCollection.Empty.FileNameToContentTypeMap.ToBuilder();
                foreach (var fileExtensionDefinition in this.FileToContentTypeProductions)
                {
                    // MEF ensures that there will be at least one content type in the metadata. We take the first one. 
                    // We prefer this over defining a different attribute from ContentType[] for this purpose.
                    var contentTypeName = fileExtensionDefinition.Metadata.ContentTypes.FirstOrDefault();
                    ContentTypeImpl contentType;
                    if ((contentTypeName != null) && nameToContentTypeBuilder.TryGetValue(contentTypeName, out contentType))
                    {
                        if (!string.IsNullOrEmpty(fileExtensionDefinition.Metadata.FileExtension))
                        {
                            foreach (var ext in fileExtensionDefinition.Metadata.FileExtension.Split(';'))
                            {
                                if (ext != null)
                                {
                                    var extension = RemoveExtensionDot(ext);
                                    if (!(string.IsNullOrWhiteSpace(extension) || fileExtensionToContentTypeMapBuilder.ContainsKey(extension)))
                                        fileExtensionToContentTypeMapBuilder.Add(extension, contentType);
                                }
                            }
                        }

                        if (!string.IsNullOrEmpty(fileExtensionDefinition.Metadata.FileName))
                        {
                            foreach (var name in fileExtensionDefinition.Metadata.FileName.Split(';'))
                            {
                                if (!(string.IsNullOrWhiteSpace(name) || fileNameToContentTypeMapBuilder.ContainsKey(name)))
                                    fileNameToContentTypeMapBuilder.Add(name, contentType);
                            }
                        }
                    }
                }

                var newMaps = new MapCollection(nameToContentTypeBuilder.ToImmutable(), mimeTypeToContentTypeBuilder.ToImmutable(), fileExtensionToContentTypeMapBuilder.ToImmutable(), fileNameToContentTypeMapBuilder.ToImmutable());
                Interlocked.CompareExchange(ref this.maps, newMaps, oldMaps);

                // We actually don't care whether or not the CompareExchange succeeded.
                // Eitehr it succeeded (normally the case) or someone else successfully completed BuildContentTypes on another thread and we shouldn't do anything.
            }
        }