Пример #1
0
 private void DispatchLoadToExtensions()
 {
     if (Hierarchy != null)
     {
         var projectItem = VsUtils.GetProjectItem(Hierarchy, ItemId);
         if (projectItem != null)
         {
             var    fileContents = VSHelpers.GetTextFromVsTextLines(VsBuffer);
             string newBufferContents;
             List <ExtensionError> extensionErrors;
             if (StandaloneXmlModelProvider.TryGetBufferViaExtensions(
                     projectItem, fileContents, out newBufferContents, out extensionErrors))
             {
                 if (VSHelpers.CheckOutFilesIfEditable(ServiceProvider, new[] { FileName }))
                 {
                     VsUtils.SetTextForVsTextLines(VsBuffer, newBufferContents);
                 }
                 else
                 {
                     ErrorListHelper.LogExtensionErrors(
                         new List <ExtensionError>
                     {
                         new ExtensionError(
                             string.Format(
                                 CultureInfo.CurrentCulture, Resources.ExtensionError_SourceControlLock,
                                 Path.GetFileName(FileName)),
                             ErrorCodes.ExtensionsError_BufferNotEditable,
                             ExtensionErrorSeverity.Error)
                     },
                         projectItem);
                 }
             }
         }
     }
 }
Пример #2
0
        private void ProcessErrors(IList <EdmSchemaError> schemaErrors, Uri projectItemUri, EFArtifact artifact)
        {
            // since we will inevitably add *all* errors from the artifact set into the error list, we can easily
            // clear the entire error list here even though we just validate the CSDL.
            var errorList = ErrorListHelper.GetSingleDocErrorList(projectItemUri);

            if (errorList != null)
            {
                errorList.Clear();
            }

            if (artifact == null)
            {
                Debug.Fail("Where is the artifact? We should have created it at least through the temporary model manager");
                return;
            }

            // we have to remove both the RMV and SFG CSDL errors to prevent duplicates
            artifact.ArtifactSet.RemoveErrorsForArtifact(artifact, ErrorClass.Runtime_CSDL);

            // add all CSDL-based SFG errors to the artifact set
            if (schemaErrors.Count > 0)
            {
                foreach (var error in schemaErrors)
                {
                    // construct an ErrorInfo with correct line/column number and add it to the artifact set. Note that the CodeGen EdmSchemaError line
                    // refers to the line of the error inside the CSDL, so to get the line of the error in the edmx file we have to offset it by the line
                    // number where the conceptual model begins.
                    var edmxErrorLine = error.Line + artifact.ConceptualModel().GetLineNumber();
                    var efobject      = artifact.FindEFObjectForLineAndColumn(edmxErrorLine, error.Column);
                    var errorInfo     = new ErrorInfo(
                        GetErrorInfoSeverity(error), error.Message, efobject, error.ErrorCode, ErrorClass.Runtime_CSDL);
                    artifact.ArtifactSet.AddError(errorInfo);
                }
            }

            // get all the ErrorInfos for this artifact and add it to the error list
            var artifactSet = artifact.ArtifactSet;

            Debug.Assert(artifactSet != null, "Where is the artifact set for this artifact?");
            if (artifactSet != null)
            {
                var errors = artifactSet.GetArtifactOnlyErrors(artifact);
                if (errors.Count > 0)
                {
                    // resolve the hierarchy and item id for adding to the error list
                    var hierarchy = VSHelpers.GetVsHierarchy(ProjectItem.ContainingProject, Services.ServiceProvider);
                    var itemId    = VsUtils.GetProjectItemId(hierarchy, ProjectItem);

                    Debug.Assert(hierarchy != null, "Why isn't there a hierarchy associated with this project item?");
                    Debug.Assert(itemId != VSConstants.VSITEMID_NIL, "There should be an item ID associated with this project item");

                    if (hierarchy != null &&
                        itemId != VSConstants.VSITEMID_NIL)
                    {
                        ErrorListHelper.AddErrorInfosToErrorList(errors, hierarchy, itemId);
                    }
                }
            }
        }
Пример #3
0
        protected override void ClearErrorList(Uri oldUri, Uri newUri)
        {
            // clear out the error list so after the rename the errors are bound to the correct artifacts
            ErrorListHelper.ClearErrorsForDocAcrossLists(newUri);

            // for a save-as the errors are associated with the oldUri
            ErrorListHelper.ClearErrorsForDocAcrossLists(oldUri);
        }
Пример #4
0
        // <summary>
        //     This will do analysis to determine if a document should be opened
        //     only in the XmlEditor.
        // </summary>
        internal override void DetermineIfArtifactIsDesignerSafe()
        {
            VsUtils.EnsureProvider(this);

            base.DetermineIfArtifactIsDesignerSafe();
            //
            // TODO:  we need to figure out how to deal with errors from the wizard.
            //        when we clear the error list below, we lose errors that we put into the error
            //        list when running the wizard.
            //

            //
            // Now update the VS error list with all of the errors we want to display, which are now in the EFArtifactSet.
            //
            var errorInfos = ArtifactSet.GetAllErrors();

            if (errorInfos.Count > 0)
            {
                var currentProject = VSHelpers.GetProjectForDocument(Uri.LocalPath, PackageManager.Package);
                if (currentProject != null)
                {
                    var hierarchy = VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider);
                    if (hierarchy != null)
                    {
                        var fileFinder = new VSFileFinder(Uri.LocalPath);
                        fileFinder.FindInProject(hierarchy);

                        Debug.Assert(fileFinder.MatchingFiles.Count <= 1, "Unexpected count of matching files in project");

                        // if the EDMX file is not part of the project.
                        if (fileFinder.MatchingFiles.Count == 0)
                        {
                            var docData = VSHelpers.GetDocData(PackageManager.Package, Uri.LocalPath) as IEntityDesignDocData;
                            ErrorListHelper.AddErrorInfosToErrorList(errorInfos, docData.Hierarchy, docData.ItemId);
                        }
                        else
                        {
                            foreach (var vsFileInfo in fileFinder.MatchingFiles)
                            {
                                if (vsFileInfo.Hierarchy == VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider))
                                {
                                    var errorList = ErrorListHelper.GetSingleDocErrorList(vsFileInfo.Hierarchy, vsFileInfo.ItemId);
                                    if (errorList != null)
                                    {
                                        errorList.Clear();
                                        ErrorListHelper.AddErrorInfosToErrorList(errorInfos, vsFileInfo.Hierarchy, vsFileInfo.ItemId);
                                    }
                                    else
                                    {
                                        Debug.Fail("errorList is null!");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //
        // Construct and initialize a new parsing session, using the given lexer.
        //
        // Also sets up error provision infrastructure, so that exceptions thrown
        // during the parsing process can be routed to the VS UI (as IntelliSense
        // errors or other "fix me" hints).
        //
        public ParseSession(LexSession lexer)
        {
            Lexer = lexer;

            var helper = new ErrorListHelper();

            ErrorProvider = new ErrorListProvider(helper);
            ErrorProvider.ProviderName = "Epoch Language";
            ErrorProvider.ProviderGuid = new Guid(VsPackage.PackageGuid);
        }
Пример #6
0
        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initialization code that rely on services provided by VisualStudio.
        /// </summary>
        protected override void Initialize()
        {
            // Get directory of the currently opened solution.
            var dte2 = (DTE2)Package.GetGlobalService(typeof(SDTE));

            if (dte2 != null)
            {
                // Init linter.
                TsLint.Init(dte2);

                // Init Error List helper.
                ErrorListHelper.Init(this);
            }

            base.Initialize();
        }
        /// <summary>
        ///     When the user builds through the command line, we only load the necessary, non-UI functionality:
        ///     1. Xml Editor package for XLinq tree
        ///     2. Model Manager
        ///     3. Connection Manager and listener
        ///     4. Error List, and notifications that perform our specialized validation on build
        /// </summary>
        private void InitializeForCommandLineBuilds()
        {
            PackageManager.Package = this;
            _dispatcher            = Dispatcher.CurrentDispatcher;

            // make sure that we can load the XML Editor package
            var vsShell = (IVsShell)GetService(typeof(SVsShell));

            if (vsShell != null)
            {
                var        editorPackageGuid = CommonPackageConstants.xmlEditorPackageGuid;
                IVsPackage editorPackage;
                NativeMethods.ThrowOnFailure(vsShell.LoadPackage(ref editorPackageGuid, out editorPackage));
            }

            ErrorListHelper.RegisterForNotifications();
        }
Пример #8
0
        protected override void Initialize()
        {
            base.Initialize();

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve;

            try
            {
                RegisterProjectFactory(new ClojureProjectFactory(this));
                RegisterCommandMenuService();
                HideAllClojureEditorMenuCommands();
                EnableTokenizationOfNewClojureBuffers();
                SetupNewClojureBuffersWithSpacingOptions();
                EnableMenuCommandsOnNewClojureBuffers();
                ShowClojureProjectMenuCommands();
                _errorListHelper = new ErrorListHelper();

                Thread delayedStartup = new Thread(() =>
                {
                    try
                    {
                        EnableSettingOfRuntimePathForNewClojureProjectsOnFirstInstall();
                        UnzipRuntimes();

                        HippieCompletionSource.Initialize(this);
                        _metadata = new Metadata(); // SlowLoadingProcess for the 1st time.
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(string.Format("Unhandled Exception loading vsClojure : {0}{1}Stack Trace: {2}", e.Message, System.Environment.NewLine, e.StackTrace));
                    }
                });
                delayedStartup.IsBackground = true;
                delayedStartup.Start();
            }
            catch (Exception e)
            {
                MessageBox.Show(string.Format("Unhandled Exception loading vsClojure : {0}{1}Stack Trace: {2}", e.Message, System.Environment.NewLine, e.StackTrace));
            }
        }
        public void RunFinished()
        {
            if (_edmxItem == null)
            {
                return;
            }

            var fileExtension = Path.GetExtension(_edmxItem.FileNames[1]);

            Debug.Assert(
                _activeSolutionProject.Equals(_edmxItem.ContainingProject),
                "ActiveSolutionProject is not the EDMX file's containing project");
            using (new VsUtils.HourglassHelper())
            {
                var    package = PackageManager.Package;
                Window window  = null;

                try
                {
                    ConfigFileUtils.UpdateConfig(_modelBuilderSettings);

                    // save the model generated in the wizard UI.
                    if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase)
                    {
                        var writingModelWatch = new Stopwatch();
                        writingModelWatch.Start();
                        var mbe = _modelBuilderSettings.ModelBuilderEngine;

                        if (!string.Equals(fileExtension, EntityDesignArtifact.EXTENSION_EDMX, StringComparison.OrdinalIgnoreCase))
                        {
                            // convert the file if this isn't EDMX
                            var edmxFileInfo      = new FileInfo(_edmxItem.FileNames[1]);
                            var conversionContext = new ModelConversionContextImpl(
                                _edmxItem.ContainingProject,
                                _edmxItem,
                                edmxFileInfo,
                                _modelBuilderSettings.TargetSchemaVersion,
                                mbe.Model);
                            VSArtifact.DispatchToConversionExtensions(
                                EscherExtensionPointManager.LoadModelConversionExtensions(),
                                fileExtension,
                                conversionContext,
                                loading: false);
                            File.WriteAllText(edmxFileInfo.FullName, conversionContext.OriginalDocument);
                        }
                        else
                        {
                            // we need to use XmlWriter to output so that XmlDeclaration is preserved.
                            using (var modelWriter = XmlWriter.Create(
                                       _edmxItem.FileNames[1],
                                       new XmlWriterSettings {
                                Indent = true
                            }))
                            {
                                mbe.Model.WriteTo(modelWriter);
                            }
                        }

                        writingModelWatch.Stop();
                        VsUtils.LogOutputWindowPaneMessage(
                            _edmxItem.ContainingProject,
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Properties.Resources.WritingModelTimeMsg,
                                writingModelWatch.Elapsed));

                        // now add errors
                        ErrorListHelper.LogWizardErrors(mbe.Errors, _edmxItem);
                    }

                    // set the ItemType for the generated .edmx file
                    if (_modelBuilderSettings.VSApplicationType != VisualStudioProjectSystem.Website &&
                        string.Equals(
                            fileExtension,
                            EntityDesignArtifact.EXTENSION_EDMX,
                            StringComparison.OrdinalIgnoreCase))
                    {
                        _edmxItem.Properties.Item(ItemTypePropertyName).Value = EntityDeployBuildActionName;
                    }

                    // now open created file in VS using default viewer
                    try
                    {
                        window = _edmxItem.Open(Constants.vsViewKindPrimary);
                        Debug.Assert(window != null, "Unable to get window for created edmx file");
                    }
                    catch (ObjectDisposedException)
                    {
                        PackageManager.Package.ModelGenErrorCache.RemoveErrors(_edmxItem.get_FileNames(1));
                    }
                }
                finally
                {
                    package.ModelGenErrorCache.RemoveErrors(_edmxItem.FileNames[1]);
                }

                // Construct an editing context and make all final edits that require the file is opened.
                var edmxFileUri    = new Uri(_edmxItem.FileNames[1]);
                var designArtifact =
                    package.ModelManager.GetNewOrExistingArtifact(
                        edmxFileUri, new VSXmlModelProvider(package, package)) as EntityDesignArtifact;
                Debug.Assert(
                    designArtifact != null,
                    "artifact should be of type EntityDesignArtifact but received type " + designArtifact.GetType().FullName);
                Debug.Assert(
                    designArtifact.StorageModel != null, "designArtifact StorageModel cannot be null for Uri " + edmxFileUri.AbsolutePath);
                Debug.Assert(
                    designArtifact.ConceptualModel != null,
                    "designArtifact ConceptualModel cannot be null for Uri " + edmxFileUri.AbsolutePath);

                if (designArtifact != null &&
                    designArtifact.StorageModel != null &&
                    designArtifact.ConceptualModel != null)
                {
                    var designerSafeBeforeAddingTemplates = designArtifact.IsDesignerSafe;

                    var editingContext =
                        package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(designArtifact.Uri);
                    Debug.Assert(editingContext != null, "Null EditingContext for artifact " + edmxFileUri.AbsolutePath);
                    if (editingContext != null)
                    {
                        // Add DbContext templates when generation is GenerateFromDatabase. (connection is configured)
                        if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase)
                        {
                            new DbContextCodeGenerator().AddDbContextTemplates(
                                _edmxItem,
                                _modelBuilderSettings.UseLegacyProvider);
                        }

                        // Create FunctionImports for every new Function
                        var cp = PrepareCommandsAndIntegrityChecks(_modelBuilderSettings, editingContext, designArtifact);

                        if (DbContextCodeGenerator.TemplateSupported(_edmxItem.ContainingProject, package))
                        {
                            // Add command setting CodeGenerationStrategy to "None" for EmptyModel. (connection is not yet configured)
                            // NOTE: For EmptyModel, the templates will be added after the connection is configured.
                            //       (i.e. during "Generate Database from Model" or "Refresh from Database")
                            if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.EmptyModel)
                            {
                                var cmd = EdmUtils.SetCodeGenStrategyToNoneCommand(designArtifact);
                                if (cmd != null)
                                {
                                    if (cp == null)
                                    {
                                        var cpc = new CommandProcessorContext(
                                            editingContext,
                                            EfiTransactionOriginator.CreateNewModelId,
                                            Resources.Tx_SetCodeGenerationStrategy);
                                        cp = new CommandProcessor(cpc, cmd);
                                    }
                                    else
                                    {
                                        cp.EnqueueCommand(cmd);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Templates not supported, add reference to SDE. (.NET Framework 3.5)
                            VsUtils.AddProjectReference(_edmxItem.ContainingProject, "System.Data.Entity");
                        }

                        if (cp != null)
                        {
                            cp.Invoke();
                        }

                        // save the artifact to make it look as though updates were part of creation
                        _edmxItem.Save();

                        if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase &&
                            !designerSafeBeforeAddingTemplates)
                        {
                            // If the artifact became safe after adding references we need to reload it (this can happen
                            // on .NET Framework 4 where we would originally create a v3 edmx if the user selected EF6 -
                            // the artifact will be flagged as invalid since there is no runtime which could handle v3
                            // but after we added references to EF6 the artifacts becomes valid and need to be reloaded).
                            designArtifact.DetermineIfArtifactIsDesignerSafe();
                            if (designArtifact.IsDesignerSafe)
                            {
                                Debug.Assert(!designArtifact.IsDirty, "Reloading dirty artifact - changes will be lost.");

                                // Since the artifact was originally not valid we did not create the diagram for it.
                                // Using ReloadDocData will cause the diagram to be recreated. Note we don't need to
                                // reload the artifact itself since it has not changed.
                                ((DocData)
                                 VSHelpers.GetDocData(package, designArtifact.Uri.LocalPath)).ReloadDocData(0);
                            }
                        }
                    }

                    if (window != null)
                    {
                        window.Activate();
                    }
                }
            }
        }
Пример #10
0
        internal string DispatchSaveToExtensions(
            IServiceProvider serviceProvider, ProjectItem projectItem, string fileContents,
            Lazy <IModelConversionExtension, IEntityDesignerConversionData>[] converters,
            Lazy <IModelTransformExtension>[] serializers)
        {
            Debug.Assert(projectItem != null, "projectItem != null");
            Debug.Assert(fileContents != null, "bufferText != null");
            Debug.Assert(serializers != null && converters != null, "extensions must not be null");
            Debug.Assert(serializers.Any() || converters.Any(), "at least one extension expected");

            ModelTransformContextImpl  transformContext  = null;
            ModelConversionContextImpl conversionContext = null;

            try
            {
                var original            = XDocument.Parse(fileContents, LoadOptions.PreserveWhitespace);
                var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, serviceProvider);
                Debug.Assert(targetSchemaVersion != null, "we should not get here for Misc projects");

                transformContext = new ModelTransformContextImpl(projectItem, targetSchemaVersion, original);

                // call the extensions that can save EDMX files first (even if we aren't going to end up in an EDMX file, let them process)
                VSArtifact.DispatchToSerializationExtensions(serializers, transformContext, loading: false);

                // get the extension of the file being loaded (might not be EDMX); this API will include the preceeding "."
                var fileInfo      = new FileInfo(FileName);
                var fileExtension = fileInfo.Extension;

                // now if this is not an EDMX file, hand off to the extension who can convert it to the writable content
                if (!string.Equals(fileExtension, EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase))
                {
                    // the current document coming from the serializers becomes our original
                    conversionContext = new ModelConversionContextImpl(
                        projectItem.ContainingProject, projectItem, fileInfo, targetSchemaVersion, transformContext.CurrentDocument);

                    // we aren't loading an EDMX file, so call the extensions who can process this file extension
                    // when this finishes, then output should be a valid EDMX document
                    VSArtifact.DispatchToConversionExtensions(converters, fileExtension, conversionContext, false);

                    // we are done saving, so get bufferText from the OriginalDocument
                    // TODO use Utf8StringWriter here somehow?
                    return(conversionContext.OriginalDocument);
                }
                else
                {
                    // we are saving an EDMX file, so get bufferText from the XDocument
                    using (var writer = new Utf8StringWriter())
                    {
                        transformContext.CurrentDocument.Save(writer, SaveOptions.None);
                        return(writer.ToString());
                    }
                }
            }
            catch (XmlException)
            {
                // Don't do anything here. We will want to gracefully step out of the extension loading
                // and let the core designer handle this.
                return(fileContents);
            }
            finally
            {
                var errorList = ErrorListHelper.GetExtensionErrorList(serviceProvider);
                errorList.Clear();

                // log any errors
                if (conversionContext != null)
                {
                    if (conversionContext.Errors.Count > 0)
                    {
                        ErrorListHelper.LogExtensionErrors(conversionContext.Errors, projectItem);
                    }
                    conversionContext.Dispose();
                }

                if (transformContext != null)
                {
                    if (transformContext.Errors.Count > 0)
                    {
                        ErrorListHelper.LogExtensionErrors(transformContext.Errors, projectItem);
                    }
                    transformContext.Dispose();
                }
            }
        }
Пример #11
0
        public bool CreateAndLoadBuffer()
        {
            DestroyBuffer();

            var pkg = PackageManager.Package as Package;
            IServiceProvider serviceProvider = pkg;

            var textLinesType = typeof(VSTextManagerInterop.IVsTextLines);
            var riid          = textLinesType.GUID;
            var clsid         = typeof(VSTextManagerInterop.VsTextBufferClass).GUID;

            _underlyingBuffer = pkg.CreateInstance(ref clsid, ref riid, textLinesType);
            Debug.Assert(_underlyingBuffer != null, "Failure while creating buffer.");

            var buffer = _underlyingBuffer as VSTextManagerInterop.IVsTextLines;

            Debug.Assert(buffer != null, "Why does buffer not implement IVsTextLines?");

            var ows = buffer as IObjectWithSite;

            if (ows != null)
            {
                ows.SetSite(serviceProvider.GetService(typeof(IOleServiceProvider)));
            }

            // We want to set the LanguageService SID explicitly to the XML Language Service.
            // We need turn off GUID_VsBufferDetectLangSID before calling LoadDocData so that the
            // TextBuffer does not do the work to detect the LanguageService SID from the file extension.
            var userData = buffer as VSTextManagerInterop.IVsUserData;

            if (userData != null)
            {
                var VsBufferDetectLangSID = new Guid("{17F375AC-C814-11d1-88AD-0000F87579D2}"); //GUID_VsBufferDetectLangSID;
                VSErrorHandler.ThrowOnFailure(userData.SetData(ref VsBufferDetectLangSID, false));
            }

            var langSid = CommonPackageConstants.xmlEditorLanguageService;

            VSErrorHandler.ThrowOnFailure(buffer.SetLanguageServiceID(ref langSid));

            var persistDocData = buffer as IVsPersistDocData;

            if (persistDocData != null)
            {
                persistDocData.LoadDocData(FileName);
                var artifactUri = new Uri(FileName);

                var artifact = PackageManager.Package.ModelManager.GetArtifact(artifactUri);
                if (artifact != null &&
                    artifact.IsCodeGenArtifact)
                {
                    var standaloneProvider = artifact.XmlModelProvider as StandaloneXmlModelProvider;
                    if (standaloneProvider.ExtensionErrors == null ||
                        standaloneProvider.ExtensionErrors.Count == 0)
                    {
                        // If there is a cached code gen artifact, it will have loaded its text buffer using extensions already.
                        // Therefore we can grab the text buffer from that artifact for our docdata buffer, and dispose the
                        // code gen artifact since it's using a XmlProvider that is standalone and won't be supported by the
                        // designer.
                        var projectItem = VsUtils.GetProjectItem(Hierarchy, ItemId);
                        if (projectItem != null)
                        {
                            if (VSHelpers.CheckOutFilesIfEditable(ServiceProvider, new[] { FileName }))
                            {
                                string artifactText = null;
                                using (var writer = new Utf8StringWriter())
                                {
                                    artifact.XDocument.Save(writer, SaveOptions.None);
                                    artifactText = writer.ToString();
                                }

                                if (!String.IsNullOrWhiteSpace(artifactText))
                                {
                                    VsUtils.SetTextForVsTextLines(VsBuffer, artifactText);
                                }
                            }
                            else
                            {
                                ErrorListHelper.LogExtensionErrors(
                                    new List <ExtensionError>
                                {
                                    new ExtensionError(
                                        string.Format(
                                            CultureInfo.CurrentCulture, Resources.ExtensionError_SourceControlLock,
                                            Path.GetFileName(FileName)),
                                        ErrorCodes.ExtensionsError_BufferNotEditable,
                                        ExtensionErrorSeverity.Error)
                                },
                                    projectItem);
                            }
                        }

                        PackageManager.Package.ModelManager.ClearArtifact(artifactUri);
                    }
                    else
                    {
                        // If the extensions ran into errors whilst loading, we'll need to re-run extensions anyway so we ignore the cache
                        PackageManager.Package.ModelManager.ClearArtifact(artifactUri);
                        DispatchLoadToExtensions();
                    }
                }
                else
                {
                    DispatchLoadToExtensions();
                }
            }

            // DSL exposes the FileNameChanged event which we subscribe to so we can update the moniker inside
            // the text buffer, which is required to update our model as well as keep the XmlModel in sync.
            FileNameChanged += OnFileNameChanged;
            RegisterUndoTracking();
            return(true);
        }
        internal static void UpdateModelFromDatabase(EntityDesignArtifact artifact)
        {
            VsUtils.EnsureProvider(artifact);

            var project         = VSHelpers.GetProjectForDocument(artifact.Uri.LocalPath, PackageManager.Package);
            var serviceProvider = Services.ServiceProvider;

            // set up ModelBuilderSettings for startMode=PerformDatabaseConfigAndSelectTables
            ModelBuilderWizardForm.WizardMode startMode;
            ModelBuilderSettings settings;

            ModelBuilderEngine.SetupSettingsAndModeForDbPages(
                serviceProvider, project, artifact, true,
                ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables,
                ModelBuilderWizardForm.WizardMode.PerformSelectTablesOnly, out startMode, out settings);
            settings.WizardKind = WizardKind.UpdateModel;

            // use existing storage namespace as new storage namespace
            if (null != artifact.StorageModel() &&
                null != artifact.StorageModel().Namespace &&
                !string.IsNullOrEmpty(artifact.StorageModel().Namespace.Value))
            {
                settings.StorageNamespace = artifact.StorageModel().Namespace.Value;
            }

            // use existing model namespace as new model namespace (this only affects the temporary
            // artifact but there is a situation where the C-side EntityContainer has been given the
            // same name as the default model namespace where not setting this causes the temporary
            // artifact to be unreadable because of symbol clashes)
            if (null != artifact.ConceptualModel() &&
                null != artifact.ConceptualModel().Namespace &&
                !string.IsNullOrEmpty(artifact.ConceptualModel().Namespace.Value))
            {
                settings.ModelNamespace = artifact.ConceptualModel().Namespace.Value;
            }

            settings.ModelBuilderEngine = new UpdateModelFromDatabaseModelBuilderEngine();

            // call the ModelBuilderWizardForm
            var form = new ModelBuilderWizardForm(serviceProvider, settings, startMode);

            try
            {
                form.Start();
            }
            catch (Exception e)
            {
                VsUtils.ShowErrorDialog(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.ModelObjectItemWizard_UnexpectedExceptionHasOccurred,
                        e.Message));
                return;
            }

            // if Wizard was cancelled or the user hit 'X' to close window
            // no need for any further action
            if (form.WizardCancelled ||
                !form.WizardFinished)
            {
                return;
            }

            // Update the app. or web.config, register build providers etc
            ConfigFileUtils.UpdateConfig(settings);

            // clear all previous errors for this document first
            ErrorListHelper.ClearErrorsForDocAcrossLists(settings.Artifact.Uri);

            // log any errors that occurred during model-gen to the error list
            ErrorListHelper.LogUpdateModelWizardErrors(settings.ModelBuilderEngine.Errors, settings.Artifact.Uri.LocalPath);

            // use form.ModelBuilderSettings to look at accumulated info and
            // take appropriate action
            var editingContext       = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(artifact.Uri);
            var shouldReloadArtifact = ProcessAccumulatedInfo(editingContext, artifact, settings);

            // If database was configured, add DbContext templates
            if (startMode == ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables)
            {
                var edmxItem = VsUtils.GetProjectItemForDocument(artifact.Uri.LocalPath, serviceProvider);
                new DbContextCodeGenerator().AddDbContextTemplates(edmxItem, settings.UseLegacyProvider);
            }

            // We can reload only after we added EF references to the project otherwise we would get a watermark
            // saying that the schema version does not match the referenced EF version which would not be true.
            // If we reload becuase there was an extension that potentially modified the artifact then it does not matter.
            if (shouldReloadArtifact)
            {
                artifact.ReloadArtifact();
                artifact.IsDirty = true;
            }
        }
        protected override void Initialize()
        {
            base.Initialize();

            // for command line builds we only have a minimal set of functionality to only support building
            if (IsBuildingFromCommandLine)
            {
                InitializeForCommandLineBuilds();
            }
            else
            {
                // HACK HACK -- find a better place to do this.
                EFModelErrorTaskNavigator.DslDesignerOnNavigate = DSLDesignerNavigationHelper.NavigateTo;
                // --

                HostContext.Instance.LogUpdateModelWizardErrorAction = ErrorListHelper.LogUpdateModelWizardError;
                PackageManager.Package = this;
                _dispatcher            = Dispatcher.CurrentDispatcher;

                // make sure that we can load the XML Editor package
                var vsShell = (IVsShell)GetService(typeof(SVsShell));
                if (vsShell != null)
                {
                    var        editorPackageGuid = CommonPackageConstants.xmlEditorPackageGuid;
                    IVsPackage editorPackage;
                    NativeMethods.ThrowOnFailure(vsShell.LoadPackage(ref editorPackageGuid, out editorPackage));
                }

                _documentFrameMgr         = new EntityDesignDocumentFrameMgr(PackageManager.Package);
                _modelChangeEventListener = new ModelChangeEventListener();
                _guidsCache         = new AggregateProjectTypeGuidCache();
                _modelGenErrorCache = new ModelGenErrorCache();
                _connectionManager  = new ConnectionManager();

                AddToolWindow(typeof(MappingDetailsWindow));

                // Register for VS Events
                ErrorListHelper.RegisterForNotifications();

                // Add the handler to show our Explorer. This is for the top-level 'Entity Data Model Browser' command that is added to the
                // 'View' main menu. This is different from the 'Model Browser' command on the designer context menu.
                _viewExplorerCmd = AddCommand(
                    ShowExplorerWindow, ShowExplorerWindow_BeforeQueryStatus, MicrosoftDataEntityDesignCommands.ViewExplorer);

                // Add the handler to show our MappingDesigner. This is for the top-level 'Entity Data Model Mapping Details' command that is added
                // to the 'View' main menu. This is different from the 'Mapping Details' command on the designer context menu.
                _viewMappingCmd = AddCommand(
                    ShowMappingDetailsWindow, ShowMappingDetailsWindow_BeforeQueryStatus, MicrosoftDataEntityDesignCommands.ViewMapping);

                // Subscribe to Project's target framework retargeting
                var projectRetargetingService = GetService(typeof(SVsTrackProjectRetargeting)) as IVsTrackProjectRetargeting;
                Debug.Assert(null != projectRetargetingService, "TrackProjectRetargeting service is null");
                _trackProjectRetargetingEventsCookie = 0;
                if (projectRetargetingService != null)
                {
                    projectRetargetingService.AdviseTrackProjectRetargetingEvents(this, out _trackProjectRetargetingEventsCookie);
                }

                // There is no SQL CE support dev12 onward, so removing the references

#if (VS11)
                // Subscribe to the SQL CE and SqlDatabaseFile upgrade services
                var sqlCeUpgradeService = GetGlobalService(typeof(IVsSqlCeUpgradeService)) as IVsSqlCeUpgradeService;
#endif

                var sqlDatabaseFileUpgradeService =
                    GetGlobalService(typeof(IVsSqlDatabaseFileUpgradeService)) as IVsSqlDatabaseFileUpgradeService;

#if (VS12ORNEWER)
                if (sqlDatabaseFileUpgradeService == null)
#else
                if (sqlCeUpgradeService == null ||
                    sqlDatabaseFileUpgradeService == null)
#endif
                {
                    // attempt to start IVsSqlCeUpgradeService and IVsSqlDatabaseFileUpgradeService
                    BootstrapVSDesigner();

#if (VS11)
                    if (sqlCeUpgradeService == null)
                    {
                        sqlCeUpgradeService = GetGlobalService(typeof(IVsSqlCeUpgradeService)) as IVsSqlCeUpgradeService;
                    }
#endif

                    if (sqlDatabaseFileUpgradeService == null)
                    {
                        sqlDatabaseFileUpgradeService =
                            GetGlobalService(typeof(IVsSqlDatabaseFileUpgradeService)) as IVsSqlDatabaseFileUpgradeService;
                    }
                }

#if (VS11)
                Debug.Assert(null != sqlCeUpgradeService, "sqlCeUpgradeService service is null");
                if (sqlCeUpgradeService != null)
                {
                    sqlCeUpgradeService.OnUpgradeProject += EdmUtils.SqlCeUpgradeService_OnUpgradeProject;
                }
#endif

                Debug.Assert(null != sqlDatabaseFileUpgradeService, "sqlDatabaseFileUpgradeService service is null");
                if (sqlDatabaseFileUpgradeService != null)
                {
                    sqlDatabaseFileUpgradeService.OnUpgradeProject += EdmUtils.SqlDatabaseFileUpgradeService_OnUpgradeProject;
                }
            }
        }
        protected override void Dispose(bool disposing)
        {
            try
            {
                // HACK HACK -- change when the hack is removed above
                EFModelErrorTaskNavigator.DslDesignerOnNavigate = null;
                // --

                // always dispose and null out items that use VS resources
                _viewExplorerCmd = null;
                _viewMappingCmd  = null;

                if (_explorerWindow != null)
                {
                    _explorerWindow.Dispose();
                    _explorerWindow = null;
                }

                if (_mappingDetailsWindow != null)
                {
                    // don't need to call this, the MDF takes care of this one
                    //_mappingDetailsWindow.Dispose();
                    _mappingDetailsWindow = null;
                }

                // remove all errors
                ErrorListHelper.RemoveAll();

                // Unregister for VS Events
                ErrorListHelper.UnregisterForNotifications();

                // dispose of our classes in reverse order than we created them
                if (_connectionManager != null)
                {
                    _connectionManager.Dispose();
                    _connectionManager = null;
                }

                if (_modelChangeEventListener != null)
                {
                    _modelChangeEventListener.Dispose();
                    _modelChangeEventListener = null;
                }

                if (_documentFrameMgr != null)
                {
                    _documentFrameMgr.Dispose();
                    _documentFrameMgr = null;
                }

                _modelManager.Dispose();

#if (VS11)
                // UnSubscribe from the SQL CE upgrade service
                var sqlCeUpgradeService = GetGlobalService(typeof(IVsSqlCeUpgradeService)) as IVsSqlCeUpgradeService;
                if (sqlCeUpgradeService != null)
                {
                    sqlCeUpgradeService.OnUpgradeProject -= EdmUtils.SqlCeUpgradeService_OnUpgradeProject;
                }
#endif
                // UnSubscribe from the SqlDatabaseFile upgrade service
                var sqlDatabaseFileUpgradeService =
                    GetGlobalService(typeof(IVsSqlDatabaseFileUpgradeService)) as IVsSqlDatabaseFileUpgradeService;
                if (sqlDatabaseFileUpgradeService != null)
                {
                    sqlDatabaseFileUpgradeService.OnUpgradeProject -= EdmUtils.SqlDatabaseFileUpgradeService_OnUpgradeProject;
                }

                // clear out any static references
                PackageManager.Package   = null;
                Services.ServiceProvider = null;
                _dispatcher = null;
            }
            finally
            {
                base.Dispose(disposing);
            }
        }
Пример #15
0
 protected override void ClearErrorList(IVsHierarchy pHier, uint ItemID)
 {
     ErrorListHelper.ClearErrorsForDocAcrossLists(pHier, ItemID);
 }
        internal static bool UpdateEdmxAndEnvironment(ModelBuilderSettings settings)
        {
            var artifact = settings.Artifact as EntityDesignArtifact;

            if (artifact == null)
            {
                Debug.Fail("In trying to UpdateEdmxAndEnvironment(), No Artifact was found in the ModelBuilderSettings");
                return(false);
            }

            // Update the app. or web.config, register build providers etc
            ConfigFileHelper.UpdateConfig(settings);

            if (settings.SsdlStringReader != null &&
                settings.MslStringReader != null)
            {
                // Create the XmlReaders for the ssdl and msl text
                var ssdlXmlReader = XmlReader.Create(settings.SsdlStringReader);
                var mslXmlReader  = XmlReader.Create(settings.MslStringReader);

                // Set up our post event to clear out the error list
                var cmd = new ReplaceSsdlAndMslCommand(ssdlXmlReader, mslXmlReader);
                cmd.PostInvokeEvent += (o, e) =>
                {
                    var errorList = ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri);
                    if (errorList != null)
                    {
                        errorList.Clear();
                    }
                };

                // Update the model (all inside 1 transaction so we don't get multiple undo's/redo's)
                var editingContext =
                    PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(settings.Artifact.Uri);
                var cpc = new CommandProcessorContext(
                    editingContext,
                    EfiTransactionOriginator.GenerateDatabaseScriptFromModelId, Resources.Tx_GenerateDatabaseScriptFromModel);
                var cp = new CommandProcessor(cpc, cmd);
                var addUseLegacyProviderCommand = ModelHelper.CreateSetDesignerPropertyValueCommandFromArtifact(
                    cpc.Artifact,
                    OptionsDesignerInfo.ElementName,
                    OptionsDesignerInfo.AttributeUseLegacyProvider,
                    settings.UseLegacyProvider.ToString());
                if (addUseLegacyProviderCommand != null)
                {
                    cp.EnqueueCommand(addUseLegacyProviderCommand);
                }

                // When the user had a v2 edmx file (it can happen when creating a new empty model in a project targeting
                // .NET Framework 4 and the project does not have refereces to any of EF dlls) and selected EF6 in
                // the "create database from model" wizard we need to update the artifact to use v3 schemas otherwise
                // there will be a watermark saying that the edmx is not correct for the EF version and needs to be updated.
                // We only want to run this command if the version really changed to avoid the overhead.
                if (artifact.SchemaVersion != settings.TargetSchemaVersion)
                {
                    cp.EnqueueCommand(new RetargetXmlNamespaceCommand(artifact, settings.TargetSchemaVersion));
                }

                cp.Invoke();
            }

            // First let's get the canonical file path since DTE needs this
            if (!string.IsNullOrEmpty(settings.DdlFileName) &&
                settings.DdlStringReader != null)
            {
                var canonicalFilePath = string.Empty;
                try
                {
                    var fi = new FileInfo(settings.DdlFileName);
                    canonicalFilePath = fi.FullName;
                }
                catch (Exception e)
                {
                    Debug.Fail(
                        "We should have caught this exception '" + e.Message + "' immediately after the user clicked the 'Finish' button");
                    VsUtils.ShowErrorDialog(
                        String.Format(
                            CultureInfo.CurrentCulture, ModelWizard.Properties.Resources.ErrorCouldNotParseDdlFileName, settings.DdlFileName,
                            e.Message));
                    return(false);
                }

                // Output the DDL file, catch any Exceptions, display them, and revert
                // back to the last page of the wizard.
                try
                {
                    OutputDdl(canonicalFilePath, settings.DdlStringReader);
                }
                catch (Exception e)
                {
                    if (e.InnerException == null)
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(
                                CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdl, canonicalFilePath, e.Message));
                    }
                    else
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(
                                CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdlWithInner, canonicalFilePath,
                                e.Message, e.InnerException.Message));
                    }
                    return(false);
                }

                // Add DDL file to the project if it is inside the project
                string relativePath;
                if (VsUtils.TryGetRelativePathInProject(settings.Project, canonicalFilePath, out relativePath))
                {
                    AddDDLFileToProject(settings.Project, canonicalFilePath);
                }

                // Open the DDL file if it is not already open
                IVsUIHierarchy hier;
                uint           itemId;
                IVsWindowFrame frame;
                if (VsShellUtilities.IsDocumentOpen(
                        Services.ServiceProvider, canonicalFilePath, Guid.Empty, out hier, out itemId, out frame) == false)
                {
                    VsShellUtilities.OpenDocument(Services.ServiceProvider, canonicalFilePath);
                }
            }

            return(true);
        }
Пример #17
0
        private static bool ProcessAccumulatedInfo(
            EditingContext editingContext, EntityDesignArtifact existingArtifact, ModelBuilderSettings settings)
        {
            var schemaVersionChanged = existingArtifact.SchemaVersion != settings.TargetSchemaVersion;

            EntityDesignModelManager tempModelManager = null;
            FileInfo tempEdmxFile    = null;
            Uri      tempEdmxFileUri = null;

            try
            {
                // set up new temporary ModelManager
                // NOTE:  use an EFArtifact with VSArtifactSet.  This is so we get the in-vs behavior of artifact sets,
                // but don't rely on VS loading the model into the RDT, etc..
                tempModelManager = new EntityDesignModelManager(new EFArtifactFactory(), new VSArtifactSetFactory());

                tempEdmxFile    = ConstructTempEdmxFile(settings);
                tempEdmxFileUri = new Uri(tempEdmxFile.FullName, UriKind.Absolute);
                var tempArtifactBasedOnDatabase = tempModelManager.GetNewOrExistingArtifact(tempEdmxFileUri, new VanillaXmlModelProvider());

                // if a model generation extension has changed the model, ensure that it is
                // valid before we start to process it
                if (settings.HasExtensionChangedModel)
                {
                    ValidateArtifact(tempModelManager, tempArtifactBasedOnDatabase, WizardKind.Generate);
                }

                // Note: later we want the diagram shapes and connectors to be created in the current active diagram
                // so set TransactionContext appropriately.
                EfiTransactionContext transactionContext = null;
                var contextItem = editingContext.Items.GetValue <DiagramManagerContextItem>();
                if (contextItem != null &&
                    contextItem.DiagramManager != null)
                {
                    var activeDiagram = contextItem.DiagramManager.ActiveDiagram;
                    if (activeDiagram != null)
                    {
                        transactionContext = new EfiTransactionContext();
                        transactionContext.Add(
                            EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(activeDiagram.DiagramId));
                    }
                }

                // clear search if active (Note: in Model.Tests it is OK for below to be null)
                var explorerInfo = editingContext.Items.GetValue <ExplorerWindow.ExplorerInfo>();
                if (explorerInfo != null)
                {
                    var explorerFrame = explorerInfo._explorerFrame;
                    if (explorerFrame != null)
                    {
                        if (explorerFrame.SearchIsActive)
                        {
                            explorerFrame.ResetSearchCommand.Execute(null);
                        }
                    }
                }

                var cpc = new CommandProcessorContext(
                    editingContext, EfiTransactionOriginator.UpdateModelFromDatabaseId,
                    Resources.Tx_UpdateModelFromDatabase, null, transactionContext);

                if (schemaVersionChanged)
                {
                    // changing namespaces must be done in a separate transaction otherwise XmlEditor
                    // will not pick-up changes made to xml after namespaces are changed
                    CommandProcessor.InvokeSingleCommand(
                        cpc,
                        new RetargetXmlNamespaceCommand(existingArtifact, settings.TargetSchemaVersion));
                }

                // Update the existing artifact based on tempArtifactBasedOnDatabase
                var commands = new List <Command>();
                var cmd      = new UpdateModelFromDatabaseCommand(tempArtifactBasedOnDatabase);
                commands.Add(cmd);

                // set up our post event to clear out the error list
                cmd.PostInvokeEvent +=
                    (o, e) =>
                {
                    var errorList =
                        ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri);
                    if (errorList != null)
                    {
                        errorList.Clear();
                    }
                };

                DesignerInfo designerInfo;
                if (existingArtifact.DesignerInfo().TryGetDesignerInfo(OptionsDesignerInfo.ElementName, out designerInfo))
                {
                    var optionsDesignerInfo = designerInfo as OptionsDesignerInfo;
                    Debug.Assert(optionsDesignerInfo != null, "expected non-null optionsDesignerInfo");
                    if (optionsDesignerInfo != null)
                    {
                        // pluralization checkbox
                        AddUpdateDesignerPropertyCommand(
                            optionsDesignerInfo.CheckPluralizationInWizard,
                            OptionsDesignerInfo.AttributeEnablePluralization,
                            settings.UsePluralizationService, optionsDesignerInfo, commands);

                        // include FKs in model checkbox
                        AddUpdateDesignerPropertyCommand(
                            optionsDesignerInfo.CheckIncludeForeignKeysInModel,
                            OptionsDesignerInfo.AttributeIncludeForeignKeysInModel,
                            settings.IncludeForeignKeysInModel, optionsDesignerInfo, commands);

                        // ensure UseLegacyProvider is set
                        AddUpdateDesignerPropertyCommand(
                            optionsDesignerInfo.UseLegacyProvider,
                            OptionsDesignerInfo.AttributeUseLegacyProvider,
                            settings.UseLegacyProvider, optionsDesignerInfo, commands);
                    }
                }

                // create a new FunctionImport for every new Function created (whether composable or not)
                // (or delete Functions if ProgressDialog did not finish successfully)
                // Note: this must take place as a DelegateCommand as ProcessStoredProcedureReturnTypeInformation()
                // can depend on finding the existing Functions to delete. And it won't find them until the
                // ReplaceSsdlCommand within UpdateModelFromDatabaseCommand has executed.
                var createMatchingFunctionImportsDelegateCommand = new DelegateCommand(
                    () =>
                {
                    var functionImportCommands = new List <Command>();
                    ProgressDialogHelper.ProcessStoredProcedureReturnTypeInformation(
                        existingArtifact, settings.NewFunctionSchemaProcedures, functionImportCommands, true);

                    if (functionImportCommands.Count > 0)
                    {
                        new CommandProcessor(cpc, functionImportCommands)
                        .Invoke();
                    }
                });
                commands.Add(createMatchingFunctionImportsDelegateCommand);

                // if needed, create a command to dispatch any extensions
                if (EscherExtensionPointManager.LoadModelGenerationExtensions().Length > 0)
                {
                    var dispatchCommand = new DispatchToExtensionsCommand(settings);
                    commands.Add(dispatchCommand);
                }

                // do all the work here in one transaction
                new CommandProcessor(cpc, commands)
                .Invoke();

                // if an extension has changed the model, do a full reload
                if (schemaVersionChanged || settings.HasExtensionChangedModel)
                {
                    return(true);
                }
                else
                {
                    // reset the is-designer safe flag - this can be set incorrectly when the document is reloaded after ssdl has been updated,
                    // but csdl & msl haven't.  Here, the model is correct, but we need to get views to refresh themselves after we
                    // reset the is-designer-safe flag.
                    // Perf note: reloading the artifact can take some time - so only reload if IsDesignerSafe has changed
                    var isDesignerSafeBefore = existingArtifact.IsDesignerSafe;
                    existingArtifact.DetermineIfArtifactIsDesignerSafe();
                    var isDesignerSafeAfter = existingArtifact.IsDesignerSafe;
                    if (isDesignerSafeAfter != isDesignerSafeBefore)
                    {
                        existingArtifact.FireArtifactReloadedEvent();
                    }
                }
            }
            finally
            {
                // remove tempArtifactBasedOnDatabase to dispose EFObject's properly
                if (tempEdmxFileUri != null &&
                    tempModelManager != null)
                {
                    tempModelManager.ClearArtifact(tempEdmxFileUri);
                }

                // dispose of our temp model manager
                if (tempModelManager != null)
                {
                    tempModelManager.Dispose();
                }

                // delete temporary file
                if (tempEdmxFile != null &&
                    tempEdmxFile.Exists)
                {
                    try
                    {
                        tempEdmxFile.Delete();
                    }
                    catch (IOException)
                    {
                        // do nothing if delete fails
                    }
                }
            }

            return(false);
        }
Пример #18
0
        internal static bool TryGetBufferViaExtensions(
            IServiceProvider serviceProvider, ProjectItem projectItem, string fileContents,
            Lazy <IModelConversionExtension, IEntityDesignerConversionData>[] converters,
            Lazy <IModelTransformExtension>[] serializers, out string documentViaExtensions,
            out List <ExtensionError> errors)
        {
            Debug.Assert(serviceProvider != null, "serviceProvider != null");
            Debug.Assert(projectItem != null, "projectItem != null");
            Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(projectItem.ContainingProject, serviceProvider, false));
            Debug.Assert(serializers != null && converters != null, "extensions must not be null");
            Debug.Assert(serializers.Any() || converters.Any(), "at least one extension expected");

            errors = new List <ExtensionError>();
            documentViaExtensions = "";

            ModelConversionContextImpl conversionContext = null;
            ModelTransformContextImpl  transformContext  = null;

            try
            {
                var targetSchemaVersion =
                    EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, serviceProvider);

                Debug.Assert(targetSchemaVersion != null, "should not get here for a Misc project");

                // get the extension of the file being loaded (might not be EDMX); this API will include the preceding "."
                var       filePath         = projectItem.get_FileNames(1);
                var       fileExtension    = Path.GetExtension(filePath);
                XDocument originalDocument = null;

                // see if we are loading an EDMX file or not, and if we have any converters
                if (!string.Equals(
                        fileExtension, EntityDesignArtifact.ExtensionEdmx,
                        StringComparison.OrdinalIgnoreCase))
                {
                    conversionContext = new ModelConversionContextImpl(
                        projectItem.ContainingProject, projectItem, new FileInfo(filePath),
                        targetSchemaVersion, fileContents);

                    // we aren't loading an EDMX file, so call the extensions who can process this file extension
                    // when this finishes, then output should be a valid EDMX document
                    VSArtifact.DispatchToConversionExtensions(converters, fileExtension, conversionContext, true);

                    // we are done with the non-EDMX extensions so CurrentDocument will be a valid EDMX document
                    // create the serialization context for further extensions to act on
                    transformContext = new ModelTransformContextImpl(
                        projectItem, targetSchemaVersion, conversionContext.CurrentDocument);
                }
                else
                {
                    // we are loading an EDMX file, we can parse file contents into an XDocument
                    try
                    {
                        originalDocument = XDocument.Parse(fileContents, LoadOptions.PreserveWhitespace);
                        transformContext = new ModelTransformContextImpl(
                            projectItem, targetSchemaVersion, originalDocument);
                    }
                    catch (XmlException)
                    {
                        // If there's an error here, don't do anything. We will want to gracefully step out of the extension loading
                        // since the designer itself won't load.
                    }
                }

                if (transformContext != null &&
                    originalDocument != null)
                {
                    // now dispatch to those that want to work on EDMX files
                    VSArtifact.DispatchToSerializationExtensions(serializers, transformContext, true);

                    // TODO: this does not seem to be correct if severity is Message or Warning
                    if (transformContext.Errors.Count == 0)
                    {
                        // see if any extension changed things. Note that we need to compare the serialization of
                        // the XDocuments together since the original buffer may have different whitespace after creating the XDocument.
                        // TODO: Why not use XNode.DeepEquals()?
                        string newBufferContents;
                        using (var currentDocWriter = new Utf8StringWriter())
                        {
                            transformContext.CurrentDocument.Save(currentDocWriter, SaveOptions.None);
                            newBufferContents = currentDocWriter.ToString();
                        }

                        string originalBufferContents;
                        using (var originalDocWriter = new Utf8StringWriter())
                        {
                            originalDocument.Save(originalDocWriter, SaveOptions.None);
                            originalBufferContents = originalDocWriter.ToString();
                        }

                        if (!string.Equals(originalBufferContents, newBufferContents, StringComparison.Ordinal))
                        {
                            documentViaExtensions = newBufferContents;
                            return(true);
                        }
                    }
                    else
                    {
                        errors.AddRange(transformContext.Errors);
                        return(false);
                    }
                }
            }
            finally
            {
                var errorList = ErrorListHelper.GetExtensionErrorList(serviceProvider);
                errorList.Clear();

                // log any errors
                if (conversionContext != null &&
                    conversionContext.Errors.Count > 0)
                {
                    ErrorListHelper.LogExtensionErrors(conversionContext.Errors, projectItem);
                }

                if (transformContext != null &&
                    transformContext.Errors.Count > 0)
                {
                    ErrorListHelper.LogExtensionErrors(transformContext.Errors, projectItem);
                }
            }

            return(false);
        }