private computeHash()

in sqlite/src/blobStore.ts [391:462]


	private computeHash(): string {
		const hash = crypto.createHash('md5');
		hash.update(this.blob.contents);
		const options: CompressorOptions = { mode: 'hash' };
		const compressor = assertDefined(Compressor.getVertexCompressor(VertexLabels.range));
		const rangeHashes: Map<Id, string> = new Map();
		for (let key of Object.keys(this.blob.ranges)) {
			const range = this.blob.ranges[key];
			const rangeHash = crypto.createHash('md5').update(JSON.stringify(compressor.compress(range, options), undefined, 0)).digest('base64');
			rangeHashes.set(Number(key), rangeHash);
		}
		for (let item of Array.from(rangeHashes.values()).sort(Strings.compare)) {
			hash.update(item);
		}

		// moniker
		if (this.blob.monikers !== undefined) {
			const monikers = LiteralMap.values(this.blob.monikers).sort(Monikers.compare);
			const compressor = assertDefined(Compressor.getVertexCompressor(VertexLabels.moniker));
			for (let moniker of monikers) {
				const compressed = compressor.compress(moniker, options);
				hash.update(JSON.stringify(compressed, undefined, 0));
			}
		}

		// Assume that folding ranges are already sorted
		if (this.blob.foldingRanges) {
			const compressor = foldingRangeCompressor;
			for (let range of this.blob.foldingRanges) {
				const compressed = compressor.compress(range, options);
				hash.update(JSON.stringify(compressed, undefined, 0));
			}
		}
		// Unsure if we need to sort the children by range or not?
		if (this.blob.documentSymbols && this.blob.documentSymbols.length > 0) {
			const first = this.blob.documentSymbols[0];
			const compressor = lsp.DocumentSymbol.is(first) ? undefined : assertDefined(Compressor.getVertexCompressor(VertexLabels.range));
			if (compressor === undefined) {
				throw new Error(`Document symbol compression not supported`);
			}
			const inline = (result: any[], value: RangeBasedDocumentSymbol) => {
				const item: any[] = [];
				const rangeHash = assertDefined(rangeHashes.get(value.id));
				item.push(rangeHash);
				if (value.children && value.children.length > 0) {
					const children: any[] = [];
					for (let child of value.children) {
						inline(children, child);
					}
					item.push(children);
				}
				result.push(item);
			};
			let compressed: any[] = [];
			for (let symbol of (this.blob.documentSymbols as RangeBasedDocumentSymbol[])) {
				inline(compressed, symbol);
			}
			hash.update(JSON.stringify(compressed, undefined, 0));
		}

		// Diagnostics
		if (this.blob.diagnostics && this.blob.diagnostics.length > 0) {
			this.blob.diagnostics = this.blob.diagnostics.sort(Diagnostics.compare);
			const compressor = diagnosticCompressor;
			for (let diagnostic of this.blob.diagnostics) {
				let compressed = compressor.compress(diagnostic, options);
				hash.update(JSON.stringify(compressed, undefined, 0));
			}
		}

		return hash.digest('base64');
	}