getSnapshot flushes pending changes and updates the session's snapshot if needed for the given request. When callerRef is true, the returned snapshot has an extra reference for the caller (taken atomically under snapshotMu), guaranteeing it stays alive until the caller calls Deref.
( ctx context.Context, request ResourceRequest, callerRef bool, )
| 902 | // snapshot has an extra reference for the caller (taken atomically under |
| 903 | // snapshotMu), guaranteeing it stays alive until the caller calls Deref. |
| 904 | func (s *Session) getSnapshot( |
| 905 | ctx context.Context, |
| 906 | request ResourceRequest, |
| 907 | callerRef bool, |
| 908 | ) *Snapshot { |
| 909 | s.snapshotUpdateMu.Lock() |
| 910 | defer s.snapshotUpdateMu.Unlock() |
| 911 | s.cancelScheduledSnapshotUpdate() |
| 912 | |
| 913 | fileChanges, overlays, ataChanges, newConfig := s.flushChanges(ctx) |
| 914 | updateSnapshot := !fileChanges.IsEmpty() || len(ataChanges) > 0 || newConfig != nil |
| 915 | if updateSnapshot { |
| 916 | // If there are pending file changes, we need to update the snapshot. |
| 917 | // Sending the requested URI ensures that the project for this URI is loaded. |
| 918 | return s.updateSnapshot(ctx, overlays, SnapshotChange{ |
| 919 | reason: UpdateReasonRequestedLanguageServicePendingChanges, |
| 920 | fileChanges: fileChanges, |
| 921 | ataChanges: ataChanges, |
| 922 | newConfig: newConfig, |
| 923 | ResourceRequest: request, |
| 924 | }, callerRef) |
| 925 | } |
| 926 | // If there are no pending file changes, we can try to use the current snapshot. |
| 927 | s.snapshotMu.RLock() |
| 928 | snapshot := s.snapshot |
| 929 | var updateReason UpdateReason |
| 930 | if len(request.Projects) > 0 { |
| 931 | updateReason = UpdateReasonRequestedLanguageServiceProjectDirty |
| 932 | } else if request.ProjectTree != nil { |
| 933 | updateReason = UpdateReasonRequestedLoadProjectTree |
| 934 | } else if request.AutoImports != "" { |
| 935 | updateReason = UpdateReasonRequestedLanguageServiceWithAutoImports |
| 936 | } else { |
| 937 | for _, document := range request.Documents { |
| 938 | project := snapshot.GetDefaultProject(document) |
| 939 | if project == nil { |
| 940 | updateReason = UpdateReasonRequestedLanguageServiceProjectNotLoaded |
| 941 | } else if project.dirty { |
| 942 | updateReason = UpdateReasonRequestedLanguageServiceProjectDirty |
| 943 | } |
| 944 | } |
| 945 | if updateReason == UpdateReasonUnknown { |
| 946 | for _, document := range request.ConfiguredProjectDocuments { |
| 947 | if snapshot.fs.isOpenFile(document.FileName()) { |
| 948 | project := snapshot.GetDefaultProject(document) |
| 949 | if project == nil { |
| 950 | updateReason = UpdateReasonRequestedLanguageServiceProjectNotLoaded |
| 951 | } else if project.dirty { |
| 952 | updateReason = UpdateReasonRequestedLanguageServiceProjectDirty |
| 953 | } |
| 954 | } else { |
| 955 | updateReason = UpdateReasonRequestedLanguageServiceForFileNotOpen |
| 956 | } |
| 957 | } |
| 958 | } |
| 959 | } |
| 960 | if updateReason == UpdateReasonUnknown { |
| 961 | if callerRef { |
no test coverage detected