Beispiel #1
0
        protected override string ConstructTestOutputFromInputResource(string inputResourceName, object parameter)
        {
            string             v1LogText = GetResourceText(inputResourceName);
            SarifLogVersionOne v1Log     = JsonConvert.DeserializeObject <SarifLogVersionOne>(v1LogText, SarifTransformerUtilities.JsonSettingsV1Indented);
            var transformer = new SarifVersionOneToCurrentVisitor();

            transformer.VisitSarifLogVersionOne(v1Log);

            SarifLog v2Log = transformer.SarifLog;

            return(JsonConvert.SerializeObject(v2Log, SarifTransformerUtilities.JsonSettingsIndented));
        }
        public override SarifLogVersionOne VisitSarifLogVersionOne(SarifLogVersionOne v1SarifLog)
        {
            SarifLog = new SarifLog(SarifVersion.TwoZeroZero.ConvertToSchemaUri(),
                                    SarifVersion.TwoZeroZero,
                                    new List <Run>());

            foreach (RunVersionOne v1Run in v1SarifLog.Runs)
            {
                SarifLog.Runs.Add(CreateRun(v1Run));
            }

            return(null);
        }
Beispiel #3
0
        private void RunTransformationToV1Test(string logFileContents)
        {
            string transformedContents = RunTransformationCore(logFileContents, SarifVersion.OneZeroZero);

            // Finally, ensure that transformation corrected schema uri and SARIF version.
            var settings = new JsonSerializerSettings {
                ContractResolver = SarifContractResolverVersionOne.Instance
            };
            SarifLogVersionOne v1SarifLog = JsonConvert.DeserializeObject <SarifLogVersionOne>(transformedContents, settings);

            v1SarifLog.SchemaUri.Should().Be(SarifVersion.OneZeroZero.ConvertToSchemaUri());
            v1SarifLog.Version.Should().Be(SarifVersionVersionOne.OneZeroZero);
        }
        public override SarifLog VisitSarifLog(SarifLog v2SarifLog)
        {
            SarifLogVersionOne = new SarifLogVersionOne(SarifVersionVersionOne.OneZeroZero.ConvertToSchemaUri(),
                                                        SarifVersionVersionOne.OneZeroZero,
                                                        new List <RunVersionOne>());

            foreach (Run v2Run in v2SarifLog.Runs)
            {
                SarifLogVersionOne.Runs.Add(CreateRunVersionOne(v2Run));
            }

            return(null);
        }
Beispiel #5
0
        public static int Run(TransformOptions transformOptions)
        {
            try
            {
                if (transformOptions.Version < 1 || transformOptions.Version > 2)
                {
                    Console.WriteLine(MultitoolResources.ErrorInvalidTransformTargetVersion);
                    return(1);
                }

                OptionallyEmittedData dataToInsert = OptionallyEmittedData.None;
                Array.ForEach(transformOptions.DataToInsert, data => dataToInsert |= data);

                // NOTE: we don't actually utilize the dataToInsert command-line data yet...

                string fileName = CommandUtilities.GetTransformedOutputFileName(transformOptions);

                var formatting = transformOptions.PrettyPrint
                    ? Formatting.Indented
                    : Formatting.None;

                // Assume the input log is the "other" version
                if (transformOptions.Version == 2)
                {
                    SarifLogVersionOne actualLog = MultitoolFileHelpers.ReadSarifFile <SarifLogVersionOne>(transformOptions.InputFilePath, SarifContractResolverVersionOne.Instance);
                    var visitor = new SarifVersionOneToCurrentVisitor();
                    visitor.VisitSarifLogVersionOne(actualLog);

                    MultitoolFileHelpers.WriteSarifFile(visitor.SarifLog, fileName, formatting);
                }
                else
                {
                    SarifLog actualLog = MultitoolFileHelpers.ReadSarifFile <SarifLog>(transformOptions.InputFilePath);
                    var      visitor   = new SarifCurrentToVersionOneVisitor();
                    visitor.VisitSarifLog(actualLog);

                    MultitoolFileHelpers.WriteSarifFile(visitor.SarifLogVersionOne, fileName, formatting);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(1);
            }

            return(0);
        }
        public override SarifLogVersionOne VisitSarifLogVersionOne(SarifLogVersionOne v1SarifLog)
        {
            _v2LogicalLocationToIndexMap = new Dictionary <LogicalLocation, int>(LogicalLocation.ValueComparer);
            _v1KeyToV2LogicalLocationMap = new Dictionary <string, LogicalLocation>();

            SarifLog = new SarifLog(SarifVersion.Current.ConvertToSchemaUri(),
                                    SarifVersion.Current,
                                    new List <Run>(),
                                    properties: null);

            foreach (RunVersionOne v1Run in v1SarifLog.Runs)
            {
                SarifLog.Runs.Add(CreateRun(v1Run));
            }

            return(null);
        }
Beispiel #7
0
        protected override string ConstructTestOutputFromInputResource(string inputResource)
        {
            string v2LogText = GetResourceText(inputResource);

            PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(v2LogText, formatting: Formatting.Indented, out v2LogText);
            SarifLog v2Log = JsonConvert.DeserializeObject <SarifLog>(v2LogText);

            var transformer = new SarifCurrentToVersionOneVisitor
            {
                EmbedVersionTwoContentInPropertyBag = false
            };

            transformer.VisitSarifLog(v2Log);

            SarifLogVersionOne v1Log = transformer.SarifLogVersionOne;

            return(JsonConvert.SerializeObject(v1Log, SarifTransformerUtilities.JsonSettingsV1Indented));
        }
        public void AnalyzeCommandBase_PersistsSarifOneZeroZero()
        {
            string fileName = GetThisTestAssemblyFilePath();
            string path     = Path.GetTempFileName();

            try
            {
                var options = new TestAnalyzeOptions
                {
                    TargetFileSpecifiers = new string[] { fileName },
                    Verbose               = true,
                    Statistics            = true,
                    Quiet                 = true,
                    ComputeFileHashes     = true,
                    ConfigurationFilePath = TestAnalyzeCommand.DefaultPolicyName,
                    Recurse               = true,
                    OutputFilePath        = path,
                    PrettyPrint           = true,
                    Force                 = true,
                    SarifOutputVersion    = SarifVersion.OneZeroZero
                };

                var command = new TestAnalyzeCommand();
                command.DefaultPlugInAssemblies = new Assembly[] { this.GetType().Assembly };
                int returnValue = command.Run(options);

                returnValue.Should().Be(0);

                command.RuntimeErrors.Should().Be(RuntimeConditions.None);

                JsonSerializerSettings settings = new JsonSerializerSettings()
                {
                    ContractResolver = SarifContractResolverVersionOne.Instance
                };

                SarifLogVersionOne log = JsonConvert.DeserializeObject <SarifLogVersionOne>(File.ReadAllText(path), settings);
                log.Should().NotBeNull();
                log.Runs.Count.Should().Be(1);
            }
            finally
            {
                File.Delete(path);
            }
        }
Beispiel #9
0
 private SarifLog TransformFileToVersionTwo(string inputFilePath, string inputVersion)
 {
     if (inputVersion == "1.0.0")
     {
         //  Converting version 1 to version 2
         SarifLogVersionOne actualLog = ReadSarifFile <SarifLogVersionOne>(_fileSystem, inputFilePath, SarifContractResolverVersionOne.Instance);
         var visitor = new SarifVersionOneToCurrentVisitor();
         visitor.VisitSarifLogVersionOne(actualLog);
         return(visitor.SarifLog);
     }
     else
     {
         //  Converting prerelease version 2 to version 2
         return(PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                    _fileSystem.FileReadAllText(inputFilePath),
                    formatting: Formatting.None,
                    out string _));
     }
 }
        public static void ProcessLogFile(string filePath, Solution solution, string toolFormat = ToolFormat.None, bool promptOnLogConversions = true)
        {
            SarifLog log = null;

            string logText;
            string outputPath     = null;
            bool   saveOutputFile = true;

            if (toolFormat.MatchesToolFormat(ToolFormat.None))
            {
                logText = File.ReadAllText(filePath);

                Match match = MatchVersionProperty(logText);
                if (match.Success)
                {
                    string inputVersion = match.Groups["version"].Value;

                    if (inputVersion == SarifUtilities.V1_0_0)
                    {
                        // They're opening a v1 log, so we need to transform it.
                        // Ask if they'd like to save the v2 log.
                        MessageDialogCommand response = promptOnLogConversions ? PromptToSaveProcessedLog(Resources.TransformV1_DialogMessage) : MessageDialogCommand.No;

                        if (response == MessageDialogCommand.Cancel)
                        {
                            return;
                        }

                        JsonSerializerSettings settingsV1 = new JsonSerializerSettings()
                        {
                            ContractResolver = SarifContractResolverVersionOne.Instance
                        };

                        SarifLogVersionOne v1Log = JsonConvert.DeserializeObject <SarifLogVersionOne>(logText, settingsV1);
                        var transformer          = new SarifVersionOneToCurrentVisitor();
                        transformer.VisitSarifLogVersionOne(v1Log);
                        log = transformer.SarifLog;

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the transformed log.
                            outputPath = PromptForFileSaveLocation(Resources.SaveTransformedV1Log_DialogTitle, filePath);

                            if (string.IsNullOrEmpty(outputPath))
                            {
                                return;
                            }
                        }

                        logText = JsonConvert.SerializeObject(log);
                    }
                    else if (inputVersion != VersionConstants.StableSarifVersion)
                    {
                        // It's an older v2 version, so send it through the pre-release compat transformer.
                        // Ask if they'd like to save the transformed log.
                        MessageDialogCommand response = promptOnLogConversions ? PromptToSaveProcessedLog(string.Format(Resources.TransformPrereleaseV2_DialogMessage, VersionConstants.StableSarifVersion)) : MessageDialogCommand.No;

                        if (response == MessageDialogCommand.Cancel)
                        {
                            return;
                        }

                        log = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(logText, Formatting.Indented, out logText);

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the transformed log.
                            outputPath = PromptForFileSaveLocation(Resources.SaveTransformedPrereleaseV2Log_DialogTitle, filePath);

                            if (string.IsNullOrEmpty(outputPath))
                            {
                                return;
                            }
                        }
                    }
                    else
                    {
                        // Since we didn't do any pre-processing, we don't need to write to a temp location.
                        outputPath     = filePath;
                        saveOutputFile = false;
                    }
                }
                else
                {
                    // The version property wasn't found within the first 100 characters.
                    // Per the spec, it should appear first in the sarifLog object.
                    VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider,
                                                    Resources.VersionPropertyNotFound_DialogTitle,
                                                    null, // title
                                                    OLEMSGICON.OLEMSGICON_QUERY,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return;
                }
            }
            else
            {
                // They're opening a non-SARIF log, so we need to convert it.
                // Ask if they'd like to save the converted log.
                MessageDialogCommand response = promptOnLogConversions ? PromptToSaveProcessedLog(Resources.ConvertNonSarifLog_DialogMessage) : MessageDialogCommand.No;

                if (response == MessageDialogCommand.Cancel)
                {
                    return;
                }

                var converter = new ToolFormatConverter();
                var sb        = new StringBuilder();

                using (var input = new MemoryStream(File.ReadAllBytes(filePath)))
                {
                    var outputTextWriter = new StringWriter(sb);
                    var outputJson       = new JsonTextWriter(outputTextWriter);
                    var output           = new ResultLogJsonWriter(outputJson);

                    input.Seek(0, SeekOrigin.Begin);
                    converter.ConvertToStandardFormat(toolFormat, input, output);

                    // This is serving as a flush mechanism.
                    output.Dispose();

                    logText = sb.ToString();

                    if (response == MessageDialogCommand.Yes)
                    {
                        // Prompt for a location to save the converted log.
                        outputPath = PromptForFileSaveLocation(Resources.SaveConvertedLog_DialogTitle, filePath);
                    }
                }
            }

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = Path.GetTempFileName() + ".sarif";
            }

            if (saveOutputFile)
            {
                SaveLogFile(outputPath, logText);
            }

            if (log == null)
            {
                log = JsonConvert.DeserializeObject <SarifLog>(logText);
            }

            ProcessSarifLog(log, outputPath, solution, showMessageOnNoResults: promptOnLogConversions);

            SarifTableDataSource.Instance.BringToFront();
        }
        public int Run(TransformOptions transformOptions)
        {
            try
            {
                if (transformOptions.TargetVersion != SarifVersion.OneZeroZero && transformOptions.TargetVersion != SarifVersion.Current)
                {
                    Console.WriteLine(MultitoolResources.ErrorInvalidTransformTargetVersion);
                    return(1);
                }

                OptionallyEmittedData dataToInsert = transformOptions.DataToInsert.ToFlags();

                // NOTE: we don't actually utilize the dataToInsert command-line data yet...

                string fileName = CommandUtilities.GetTransformedOutputFileName(transformOptions);

                var formatting = transformOptions.PrettyPrint
                    ? Formatting.Indented
                    : Formatting.None;


                string inputFilePath = transformOptions.InputFilePath;
                string inputVersion  = SniffVersion(inputFilePath);

                // If the user wants to transform to current v2, we check to see whether the input
                // file is v2 or pre-release v2. We upgrade both formats to current v2.
                //
                // Correspondingly, if the input file is v2 of any kind, we first ensure that it is
                // current v2, then drop it down to v1.
                //
                // We do not support transforming to any obsoleted pre-release v2 formats.
                if (transformOptions.TargetVersion == SarifVersion.Current)
                {
                    if (inputVersion == "1.0.0")
                    {
                        SarifLogVersionOne actualLog = FileHelpers.ReadSarifFile <SarifLogVersionOne>(_fileSystem, transformOptions.InputFilePath, SarifContractResolverVersionOne.Instance);
                        var visitor = new SarifVersionOneToCurrentVisitor();
                        visitor.VisitSarifLogVersionOne(actualLog);
                        FileHelpers.WriteSarifFile(_fileSystem, visitor.SarifLog, fileName, formatting);
                    }
                    else
                    {
                        // We have a pre-release v2 file that we should upgrade to current.
                        PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                            _fileSystem.ReadAllText(inputFilePath),
                            formatting: formatting,
                            out string sarifText);

                        _fileSystem.WriteAllText(fileName, sarifText);
                    }
                }
                else
                {
                    if (inputVersion == "1.0.0")
                    {
                        _fileSystem.WriteAllText(fileName, _fileSystem.ReadAllText(inputFilePath));
                    }
                    else
                    {
                        string currentSarifVersion = SarifUtilities.SemanticVersion;

                        string   sarifText = _fileSystem.ReadAllText(inputFilePath);
                        SarifLog actualLog = null;

                        if (inputVersion != currentSarifVersion)
                        {
                            // Note that we don't provide formatting here. It is not required to indent the v2 SARIF - it
                            // will be transformed to v1 later, where we should apply the indentation settings.
                            actualLog = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                                sarifText,
                                formatting: Formatting.None,
                                out sarifText);
                        }
                        else
                        {
                            actualLog = JsonConvert.DeserializeObject <SarifLog>(sarifText);
                        }

                        var visitor = new SarifCurrentToVersionOneVisitor();
                        visitor.VisitSarifLog(actualLog);

                        FileHelpers.WriteSarifFile(_fileSystem, visitor.SarifLogVersionOne, fileName, formatting, SarifContractResolverVersionOne.Instance);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(1);
            }

            return(0);
        }
Beispiel #12
0
        public int Run(TransformOptions transformOptions)
        {
            try
            {
                // Only set --output-file if --inline isn't specified. ValidateOptions will check
                // to make sure that exactly one of those two options is set.
                if (!transformOptions.Inline)
                {
                    transformOptions.OutputFilePath = CommandUtilities.GetTransformedOutputFileName(transformOptions);
                }

                bool valid = ValidateOptions(transformOptions);
                if (!valid)
                {
                    return(FAILURE);
                }

                // NOTE: we don't actually utilize the dataToInsert command-line data yet...
                OptionallyEmittedData dataToInsert = transformOptions.DataToInsert.ToFlags();

                string inputFilePath = transformOptions.InputFilePath;
                string inputVersion  = SniffVersion(inputFilePath);

                // If the user wants to transform to current v2, we check to see whether the input
                // file is v2 or pre-release v2. We upgrade both formats to current v2.
                //
                // Correspondingly, if the input file is v2 of any kind, we first ensure that it is
                // current v2, then drop it down to v1.
                //
                // We do not support transforming to any obsoleted pre-release v2 formats.
                if (transformOptions.SarifOutputVersion == SarifVersion.Current)
                {
                    if (inputVersion == "1.0.0")
                    {
                        SarifLogVersionOne actualLog = ReadSarifFile <SarifLogVersionOne>(_fileSystem, transformOptions.InputFilePath, SarifContractResolverVersionOne.Instance);
                        var visitor = new SarifVersionOneToCurrentVisitor();
                        visitor.VisitSarifLogVersionOne(actualLog);
                        WriteSarifFile(_fileSystem, visitor.SarifLog, transformOptions.OutputFilePath, transformOptions.Formatting);
                    }
                    else
                    {
                        // We have a pre-release v2 file that we should upgrade to current.
                        PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                            _fileSystem.ReadAllText(inputFilePath),
                            formatting: transformOptions.Formatting,
                            out string sarifText);

                        _fileSystem.WriteAllText(transformOptions.OutputFilePath, sarifText);
                    }
                }
                else
                {
                    if (inputVersion == "1.0.0")
                    {
                        SarifLogVersionOne logV1 = ReadSarifFile <SarifLogVersionOne>(_fileSystem, transformOptions.InputFilePath, SarifContractResolverVersionOne.Instance);
                        logV1.SchemaUri = SarifVersion.OneZeroZero.ConvertToSchemaUri();
                        WriteSarifFile(_fileSystem, logV1, transformOptions.OutputFilePath, transformOptions.Formatting, SarifContractResolverVersionOne.Instance);
                    }
                    else
                    {
                        string currentSarifVersion = SarifUtilities.StableSarifVersion;

                        string   sarifText = _fileSystem.ReadAllText(inputFilePath);
                        SarifLog actualLog = null;

                        if (inputVersion != currentSarifVersion)
                        {
                            // Note that we don't provide formatting here. It is not required to indent the v2 SARIF - it
                            // will be transformed to v1 later, where we should apply the indentation settings.
                            actualLog = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                                sarifText,
                                formatting: Formatting.None,
                                out sarifText);
                        }
                        else
                        {
                            actualLog = JsonConvert.DeserializeObject <SarifLog>(sarifText);
                        }

                        var visitor = new SarifCurrentToVersionOneVisitor();
                        visitor.VisitSarifLog(actualLog);

                        WriteSarifFile(_fileSystem, visitor.SarifLogVersionOne, transformOptions.OutputFilePath, transformOptions.Formatting, SarifContractResolverVersionOne.Instance);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }

            return(SUCCESS);
        }
        public static void ProcessLogFile(string filePath, Solution solution, string toolFormat = ToolFormat.None)
        {
            SarifLog log = null;

            JsonSerializerSettings settingsV2 = new JsonSerializerSettings()
            {
                ContractResolver = SarifContractResolver.Instance,
            };

            string logText;

            if (toolFormat.MatchesToolFormat(ToolFormat.None))
            {
                logText = File.ReadAllText(filePath);
                string pattern = @"""version""\s*:\s*""1.0.0""";
                Match  match   = Regex.Match(logText, pattern, RegexOptions.Compiled | RegexOptions.Multiline);

                if (match.Success)
                {
                    // They're opening a v1 log, so we need to transform it.
                    // Ask if they'd like to save the v2 log.
                    int result = VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider,
                                                                 Resources.TransformV1_DialogMessage,
                                                                 null, // title
                                                                 OLEMSGICON.OLEMSGICON_QUERY,
                                                                 OLEMSGBUTTON.OLEMSGBUTTON_YESNOCANCEL,
                                                                 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    MessageDialogCommand response = (MessageDialogCommand)Enum.Parse(typeof(MessageDialogCommand), result.ToString());

                    if (response == MessageDialogCommand.Cancel)
                    {
                        return;
                    }

                    JsonSerializerSettings settingsV1 = new JsonSerializerSettings()
                    {
                        ContractResolver = SarifContractResolverVersionOne.Instance,
                    };

                    SarifLogVersionOne v1Log = JsonConvert.DeserializeObject <SarifLogVersionOne>(logText, settingsV1);
                    var transformer          = new SarifVersionOneToCurrentVisitor();
                    transformer.VisitSarifLogVersionOne(v1Log);
                    log = transformer.SarifLog;

                    if (response == MessageDialogCommand.Yes)
                    {
                        // Prompt for a location to save the transformed log.
                        var saveFileDialog = new SaveFileDialog();

                        saveFileDialog.Title            = Resources.SaveTransformedV1Log_DialogTitle;
                        saveFileDialog.Filter           = "SARIF log files (*.sarif)|*.sarif";
                        saveFileDialog.RestoreDirectory = true;

                        filePath = Path.GetFileNameWithoutExtension(filePath) + ".v2.sarif";
                        saveFileDialog.FileName         = Path.GetFileName(filePath);
                        saveFileDialog.InitialDirectory = Path.GetDirectoryName(filePath);

                        if (saveFileDialog.ShowDialog() != DialogResult.OK)
                        {
                            return;
                        }

                        filePath = saveFileDialog.FileName;
                        string error = null;

                        try
                        {
                            File.WriteAllText(filePath, JsonConvert.SerializeObject(log, settingsV2));
                        }
                        catch (UnauthorizedAccessException)
                        {
                            error = string.Format(Resources.SaveTransformedV1LogFail_Access_DialogMessage, filePath);
                        }
                        catch (SecurityException)
                        {
                            error = string.Format(Resources.SaveTransformedV1LogFail_Access_DialogMessage, filePath);
                        }
                        catch (Exception ex)
                        {
                            error = string.Format(Resources.SaveTransformedV1LogFail_General_Dialog, ex.Message);
                        }

                        if (error != null)
                        {
                            VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider,
                                                            error,
                                                            null, // title
                                                            OLEMSGICON.OLEMSGICON_CRITICAL,
                                                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        }
                    }
                }
            }
            else
            {
                // We have conversion to do
                var converter = new ToolFormatConverter();
                var sb        = new StringBuilder();

                using (var input = new MemoryStream(File.ReadAllBytes(filePath)))
                {
                    var outputTextWriter = new StringWriter(sb);
                    var outputJson       = new JsonTextWriter(outputTextWriter);
                    var output           = new ResultLogJsonWriter(outputJson);

                    input.Seek(0, SeekOrigin.Begin);
                    converter.ConvertToStandardFormat(toolFormat, input, output);

                    // This is serving as a flush mechanism
                    output.Dispose();

                    logText = sb.ToString();
                }
            }

            if (log == null)
            {
                log = JsonConvert.DeserializeObject <SarifLog>(logText, settingsV2);
            }

            ProcessSarifLog(log, filePath, solution);

            SarifTableDataSource.Instance.BringToFront();
        }
Beispiel #14
0
        public static async Task ProcessLogFileCoreAsync(string filePath, string toolFormat, bool promptOnLogConversions, bool cleanErrors, bool openInEditor)
        {
            SarifLog log            = null;
            string   logText        = null;
            string   outputPath     = null;
            bool     saveOutputFile = true;

            if (toolFormat.MatchesToolFormat(ToolFormat.None))
            {
                await RetryInvokeAsync(
                    async() =>
                {
                    using (var logStreamReader = new StreamReader(filePath, Encoding.UTF8))
                    {
                        logText = await logStreamReader.ReadToEndAsync().ConfigureAwait(continueOnCapturedContext: false);
                    }
                },
                    retryInterval : TimeSpan.FromMilliseconds(300),
                    maxAttemptCount : 5);

                Match match = MatchVersionProperty(logText);
                if (match.Success)
                {
                    string inputVersion = match.Groups["version"].Value;

                    if (inputVersion == SarifUtilities.V1_0_0)
                    {
                        // They're opening a v1 log, so we need to transform it.
                        // Ask if they'd like to save the v2 log.
                        MessageDialogCommand response = promptOnLogConversions ?
                                                        await PromptToSaveProcessedLogAsync(Resources.TransformV1_DialogMessage).ConfigureAwait(continueOnCapturedContext: false) :
                                                        MessageDialogCommand.No;

                        if (response == MessageDialogCommand.Cancel)
                        {
                            return;
                        }

                        var settingsV1 = new JsonSerializerSettings()
                        {
                            ContractResolver = SarifContractResolverVersionOne.Instance,
                        };

                        SarifLogVersionOne v1Log = JsonConvert.DeserializeObject <SarifLogVersionOne>(logText, settingsV1);
                        var transformer          = new SarifVersionOneToCurrentVisitor();
                        transformer.VisitSarifLogVersionOne(v1Log);
                        log = transformer.SarifLog;

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the transformed log.
                            outputPath = await PromptForFileSaveLocationAsync(Resources.SaveTransformedV1Log_DialogTitle, filePath).ConfigureAwait(continueOnCapturedContext: false);

                            if (string.IsNullOrEmpty(outputPath))
                            {
                                return;
                            }
                        }

                        logText = JsonConvert.SerializeObject(log);
                    }
                    else if (inputVersion != VersionConstants.StableSarifVersion)
                    {
                        // It's an older v2 version, so send it through the pre-release compat transformer.
                        // Ask if they'd like to save the transformed log.
                        MessageDialogCommand response = promptOnLogConversions ?
                                                        await PromptToSaveProcessedLogAsync(string.Format(Resources.TransformPrereleaseV2_DialogMessage, VersionConstants.StableSarifVersion)).ConfigureAwait(continueOnCapturedContext: false) :
                                                        MessageDialogCommand.No;

                        if (response == MessageDialogCommand.Cancel)
                        {
                            return;
                        }

                        log = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(logText, Formatting.Indented, out logText);

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the transformed log.
                            outputPath = await PromptForFileSaveLocationAsync(Resources.SaveTransformedPrereleaseV2Log_DialogTitle, filePath).ConfigureAwait(continueOnCapturedContext: false);

                            if (string.IsNullOrEmpty(outputPath))
                            {
                                return;
                            }
                        }
                    }
                    else
                    {
                        // Since we didn't do any pre-processing, we don't need to write to a temp location.
                        outputPath     = filePath;
                        saveOutputFile = false;
                    }
                }
                else
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                    // The version property wasn't found within the first 100 characters.
                    // Per the spec, it should appear first in the sarifLog object.
                    VsShellUtilities.ShowMessageBox(ServiceProvider.GlobalProvider,
                                                    Resources.VersionPropertyNotFound_DialogTitle,
                                                    null, // title
                                                    OLEMSGICON.OLEMSGICON_QUERY,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return;
                }
            }
            else
            {
                // They're opening a non-SARIF log, so we need to convert it.
                // Ask if they'd like to save the converted log.
                MessageDialogCommand response = promptOnLogConversions ?
                                                await PromptToSaveProcessedLogAsync(Resources.ConvertNonSarifLog_DialogMessage).ConfigureAwait(continueOnCapturedContext: false) :
                                                MessageDialogCommand.No;

                if (response == MessageDialogCommand.Cancel)
                {
                    return;
                }

                // The converter doesn't have async methods, so spin
                // up a task to do this.
                await System.Threading.Tasks.Task.Run(() =>
                {
                    var sb = new StringBuilder();
                    using (FileStream fileStream = File.OpenRead(filePath))
                    {
                        using (var outputTextWriter = new StringWriter(sb))
                            using (var outputJson = new JsonTextWriter(outputTextWriter))
                                using (var output = new ResultLogJsonWriter(outputJson))
                                {
                                    var converter = new ToolFormatConverter();
                                    converter.ConvertToStandardFormat(toolFormat, fileStream, output);
                                }

                        logText = sb.ToString();

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the converted log.
                            outputPath = PromptForFileSaveLocationAsync(Resources.SaveConvertedLog_DialogTitle, filePath).Result;
                        }
                    }
                }).ConfigureAwait(continueOnCapturedContext: false);
            }

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = Path.GetTempFileName() + ".sarif";
            }

            if (saveOutputFile)
            {
                await SaveLogFileAsync(outputPath, logText).ConfigureAwait(continueOnCapturedContext: false);
            }

            if (log == null)
            {
                log = JsonConvert.DeserializeObject <SarifLog>(logText);
            }

            await ProcessSarifLogAsync(log, outputPath, cleanErrors : cleanErrors, openInEditor : openInEditor).ConfigureAwait(continueOnCapturedContext: false);
        }