func()

in src/scip-lib/partialloader/index.go [132:203]


func (p *PartialLoadedIndex) LoadIndex(indexPath string, indexReader scanner.ScipReader) error {
	localPrefixTree := &SymbolPrefixTreeNode{
		Children: make(map[model.Descriptor]*SymbolPrefixTreeNode),
	}
	localDocTreeNodes := make(map[string]*docNodes)
	localUpdatedDocs := make(map[string]int64)
	localDocToIndex := make(map[string]string)
	localImplementorsBySymbol := make(map[string]map[string]struct{})

	loadScanner := &scanner.IndexScannerImpl{
		Pool: p.pool,
		MatchSymbol: func(symbol []byte) bool {
			return !scip.IsLocalSymbol(string(symbol))
		},
		MatchDocumentPath: func(indexDocPath string) bool {
			docPath := filepath.Clean(indexDocPath)
			localDocToIndex[docPath] = indexPath
			if localDocTreeNodes[docPath] == nil {
				localDocTreeNodes[docPath] = &docNodes{
					nodes:    make([]*SymbolPrefixTreeNode, 0),
					revision: p.revision.Add(1),
				}
			}

			localUpdatedDocs[docPath] = localDocTreeNodes[docPath].revision
			p.loadedDocsMu.RLock()
			_, docLoaded := p.LoadedDocuments[docPath]
			p.loadedDocsMu.RUnlock()
			return docLoaded // We should only load the document if it had already been loaded
		},
		VisitSymbol: func(indexDocPath string, info *scip.SymbolInformation) {
			docPath := filepath.Clean(indexDocPath)
			modelInfo := mapper.ScipSymbolInformationToModelSymbolInformation(info)
			leafNode, isNew := localPrefixTree.AddSymbol(docPath, modelInfo, p.revision.Load())

			// Populate reverse implementors for quick lookup (impl -> abs)
			for _, rel := range modelInfo.Relationships {
				if rel != nil && rel.IsImplementation {
					abs := rel.Symbol
					if localImplementorsBySymbol[abs] == nil {
						localImplementorsBySymbol[abs] = make(map[string]struct{})
					}
					localImplementorsBySymbol[abs][modelInfo.Symbol] = struct{}{}
				}
			}

			if isNew {
				localDocTreeNodes[docPath].nodes = append(localDocTreeNodes[docPath].nodes, leafNode)
			}
		},
		VisitDocument: func(doc *scip.Document) {
			docPath := filepath.Clean(doc.RelativePath)
			modelDoc := mapper.ScipDocumentToModelDocument(doc)
			p.loadedDocsMu.Lock()
			p.LoadedDocuments[docPath] = modelDoc
			p.loadedDocsMu.Unlock()
			p.onDocumentLoaded(modelDoc)
		},
	}

	loadScanner.InitBuffers()
	defer func() {
		p.modificationMu.Lock()
		defer p.modificationMu.Unlock()
		p.mergePrefixTree(localPrefixTree)
		p.mergeDocTreeNodes(localDocTreeNodes)
		p.mergeUpdatedDocs(localUpdatedDocs)
		p.mergeDocToIndex(localDocToIndex)
		p.mergeImplementors(localImplementorsBySymbol)
	}()
	return loadScanner.ScanIndexReader(indexReader)
}