1515import java.util.List;
1616
1717/**
18- * Writes and merges per-source SCIP shards produced by the compiler plugin.
19- *
20- * <p>Each source file produces a self-contained {@link Index} shard containing a single {@link
21- * Document}. When a shard already exists on disk (e.g. during annotation processing rounds), the
22- * new document is merged into the existing one, deduplicating occurrences, symbols and
23- * relationships.
18+ * Writes a per-source SCIP shard, merging it with any pre-existing shard at the same path (e.g. one
19+ * written by a prior annotation-processing round).
2420 */
2521public final class ScipShardWriter {
2622
2723 private ScipShardWriter() {}
2824
29- /**
30- * Writes the given {@code shard} to {@code output}, creating parent directories as needed. If
31- * {@code output} already exists, the existing shard is parsed and merged with the new one.
32- */
3325 public static void writeOrMerge(Path output, Index shard) throws IOException {
3426 Files.createDirectories(output.getParent());
3527 if (Files.exists(output)) {
@@ -42,10 +34,7 @@ public static void writeOrMerge(Path output, Index shard) throws IOException {
4234 Files.write(output, shard.toByteArray());
4335 }
4436
45- /**
46- * Merges two SCIP shards by combining their document lists. Documents that share a {@code
47- * relative_path} have their occurrences, symbols and external symbols deduplicated.
48- */
37+ /** Merges two shards: documents sharing a {@code relative_path} are dedup-merged. */
4938 static Index merge(Index a, Index b) {
5039 Index.Builder builder = Index.newBuilder();
5140 if (b.hasMetadata()) {
@@ -68,7 +57,7 @@ static Index merge(Index a, Index b) {
6857 }
6958 builder.addAllDocuments(byPath.values());
7059
71- // External symbols: deduplicate by symbol string. Last writer wins to keep latest data.
60+ // External symbols: last writer wins to keep the most recent data.
7261 LinkedHashMap<String, SymbolInformation> externals = new LinkedHashMap<>();
7362 for (SymbolInformation s : a.getExternalSymbolsList()) externals.put(s.getSymbol(), s);
7463 for (SymbolInformation s : b.getExternalSymbolsList()) externals.put(s.getSymbol(), s);
@@ -78,18 +67,15 @@ static Index merge(Index a, Index b) {
7867 }
7968
8069 private static Document mergeDocuments(Document a, Document b) {
70+ // b.toBuilder() carries forward the most recent language/relative_path/text/encoding.
8171 Document.Builder builder = b.toBuilder().clearOccurrences().clearSymbols();
82- // Use the most recent metadata for language/relative_path/text/encoding which already
83- // come from b via toBuilder().
8472
85- // Deduplicate occurrences by (range, symbol, roles). Variants that differ only in
86- // enclosing_range get collapsed, preferring the one that carries the enclosing range.
8773 LinkedHashMap<ScipOccurrences.Key, Occurrence> occurrences = new LinkedHashMap<>();
8874 for (Occurrence occ : a.getOccurrencesList()) ScipOccurrences.put(occurrences, occ);
8975 for (Occurrence occ : b.getOccurrencesList()) ScipOccurrences.put(occurrences, occ);
9076 builder.addAllOccurrences(occurrences.values());
9177
92- // Deduplicate symbols by symbol string; merge relationships and documentation.
78+ // Dedup symbols by symbol string; merge relationships and documentation.
9379 LinkedHashMap<String, SymbolInformation> bySymbol = new LinkedHashMap<>();
9480 for (SymbolInformation info : a.getSymbolsList()) bySymbol.put(info.getSymbol(), info);
9581 for (SymbolInformation info : b.getSymbolsList()) {
@@ -103,13 +89,13 @@ private static Document mergeDocuments(Document a, Document b) {
10389
10490 private static SymbolInformation mergeSymbol(SymbolInformation a, SymbolInformation b) {
10591 SymbolInformation.Builder builder = b.toBuilder();
106- // Merge relationships, deduplicating by structural equality with deterministic ordering .
92+ // Dedup relationships by structural equality; preserve insertion order .
10793 LinkedHashMap<Relationship, Relationship> rels = new LinkedHashMap<>();
10894 for (Relationship r : a.getRelationshipsList()) rels.put(r, r);
10995 for (Relationship r : b.getRelationshipsList()) rels.put(r, r);
11096 builder.clearRelationships().addAllRelationships(rels.values());
11197
112- // Merge documentation, preserving order and avoiding duplicates .
98+ // Dedup documentation; preserve insertion order .
11399 List<String> docs = new ArrayList<>(a.getDocumentationList());
114100 for (String d : b.getDocumentationList()) {
115101 if (!docs.contains(d)) docs.add(d);
0 commit comments