public int GetFileIndex( ArtifactLocation fileLocation, bool addToFilesTableIfNotPresent = true, OptionallyEmittedData dataToInsert = OptionallyEmittedData.None, Encoding encoding = null, HashData hashData = null) { if (fileLocation == null) { throw new ArgumentNullException(nameof(fileLocation)); } if (this.Artifacts == null || this.Artifacts.Count == 0) { if (!addToFilesTableIfNotPresent) { return(-1); } } if (_artifactLocationToIndexMap == null) { InitializeFileToIndexMap(); } if (fileLocation.Uri == null) { // We only have a file index, so just return it. return(fileLocation.Index); } // Strictly speaking, some elements that may contribute to a files table // key are case sensitive, e.g., everything but the scheme and protocol of a // web URI. We don't have a proper comparer implementation that can handle // all cases. For now, we cover the Windows happy path, which assumes that // most URIs in log files are file paths (which are case-insensitive). // // Tracking item for an improved comparer: // https://github.com/Microsoft/sarif-sdk/issues/973 // When we perform a files table look-up, only the uri and uriBaseId // are relevant; these properties together comprise the unique identity // of the file object. The file index, of course, does not relate to the // file identity. We consciously exclude the properties bag as well. // We will normalize the input fileLocation.Uri to make URIs more consistent // throughout the emitted log. fileLocation.Uri = new Uri(UriHelper.MakeValidUri(fileLocation.Uri.OriginalString), UriKind.RelativeOrAbsolute); var artifactLocation = new ArtifactLocation { Uri = fileLocation.Uri, UriBaseId = fileLocation.UriBaseId }; if (!_artifactLocationToIndexMap.TryGetValue(artifactLocation, out int artifactIndex)) { if (addToFilesTableIfNotPresent) { this.Artifacts = this.Artifacts ?? new List <Artifact>(); artifactIndex = this.Artifacts.Count; Uri artifactUri = artifactLocation.TryReconstructAbsoluteUri(this.OriginalUriBaseIds, out Uri resolvedUri) ? resolvedUri : artifactLocation.Uri; var artifact = Artifact.Create( artifactUri, dataToInsert, hashData: hashData, encoding: encoding); // Copy ArtifactLocation to ensure changes to Result copy don't affect new Run.Artifacts copy artifact.Location = new ArtifactLocation(fileLocation); this.Artifacts.Add(artifact); _artifactLocationToIndexMap[artifactLocation] = artifactIndex; } else { // We did not find the item. The call was not configured to add the entry. // Return the default value that indicates the item isn't present. artifactIndex = -1; } } fileLocation.Index = artifactIndex; return(artifactIndex); }