Prevent unnecessary parsing in Acceleo LSP server.

Change-Id: I5d9a72173a348c3459f7c9cd353614a7e313a976
diff --git a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java
index f8b795f..eefad9c 100644
--- a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java
+++ b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java
@@ -34,6 +34,7 @@
 import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameResolver;
 import org.eclipse.lsp4j.Range;
 import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
+import org.eclipse.lsp4j.services.TextDocumentService;
 
 /**
  * Represents an Acceleo Text Document as known by the Language Server. It is maintained consistent with the
@@ -86,6 +87,12 @@
 	private String qualifiedName;
 
 	/**
+	 * Tells if the document is
+	 * {@link TextDocumentService#didOpen(org.eclipse.lsp4j.DidOpenTextDocumentParams) opened}.
+	 */
+	private boolean isOpened;
+
+	/**
 	 * Creates a new {@link AcceleoTextDocument} corresponding to the given URI and with the given initial
 	 * contents.
 	 * 
@@ -202,11 +209,19 @@
 	 *            the (non-{@code null}) contents of the document we are parsing.
 	 * @return the resulting {@link AcceleoAstResult}.
 	 */
-	private static AcceleoAstResult doParsing(String moduleQualifiedName, String documentContents) {
-		Objects.requireNonNull(moduleQualifiedName);
-		Objects.requireNonNull(documentContents);
-		AcceleoParser acceleoParser = new AcceleoParser();
-		return acceleoParser.parse(documentContents, moduleQualifiedName);
+	private AcceleoAstResult doParsing(String moduleQualifiedName, String documentContents) {
+		final AcceleoAstResult res;
+
+		if (isOpened()) {
+			Objects.requireNonNull(moduleQualifiedName);
+			Objects.requireNonNull(documentContents);
+			AcceleoParser acceleoParser = new AcceleoParser();
+			res = acceleoParser.parse(documentContents, moduleQualifiedName);
+		} else {
+			res = ((Module)ownerProject.getResolver().resolve(moduleQualifiedName)).getAst();
+		}
+
+		return res;
 	}
 
 	/**
@@ -477,4 +492,28 @@
 					.getEnd(), newTextExcerpt);
 		}
 	}
+
+	/**
+	 * Tells if the document is
+	 * {@link TextDocumentService#didOpen(org.eclipse.lsp4j.DidOpenTextDocumentParams) opened}.
+	 * 
+	 * @return <code>true</code> if the document is
+	 *         {@link TextDocumentService#didOpen(org.eclipse.lsp4j.DidOpenTextDocumentParams) opened},
+	 *         <code>false</code> otherwise
+	 */
+	public boolean isOpened() {
+		return isOpened;
+	}
+
+	/**
+	 * Sets if the document is {@link TextDocumentService#didOpen(org.eclipse.lsp4j.DidOpenTextDocumentParams)
+	 * opened}.
+	 * 
+	 * @param opened
+	 *            the new value
+	 */
+	public void setOpened(boolean opened) {
+		this.isOpened = opened;
+	}
+
 }
diff --git a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocumentService.java b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocumentService.java
index 019affb..522339a 100644
--- a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocumentService.java
+++ b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocumentService.java
@@ -113,6 +113,7 @@
 					+ openedDocumentUri);
 		} else {
 			this.openedDocumentsIndex.put(openedDocumentUri, openedAcceleoTextDocument);
+			openedAcceleoTextDocument.setOpened(true);
 		}
 	}
 
@@ -131,6 +132,14 @@
 	public void didClose(DidCloseTextDocumentParams params) {
 		URI closedDocumentUri = AcceleoLanguageServerServicesUtils.toUri(params.getTextDocument().getUri());
 		checkDocumentIsOpened(closedDocumentUri);
+		AcceleoTextDocument openedAcceleoTextDocument = this.server.getWorkspace().getTextDocument(
+				closedDocumentUri);
+		if (openedAcceleoTextDocument == null) {
+			throw new IllegalStateException("Could not find the Acceleo Text Document at URI "
+					+ closedDocumentUri);
+		} else {
+			openedAcceleoTextDocument.setOpened(false);
+		}
 		this.openedDocumentsIndex.remove(closedDocumentUri);
 	}
 
@@ -170,34 +179,6 @@
 	public AcceleoTextDocument findTextDocumentDefining(Module definedModule) {
 		AcceleoTextDocument definingTextDocument = null;
 
-		// // First look in the already loaded documents.
-		// for (AcceleoTextDocument candidate : this.loadedDocumentsIndex.values()) {
-		// if (documentDefinesModule(candidate, definedModule)) {
-		// definingTextDocument = candidate;
-		// break;
-		// }
-		// }
-		//
-		// if (definingTextDocument == null) {
-		// // Otherwise, search in the workspace.
-		// CompletableFuture<List<WorkspaceFolder>> futureWorkspaceFolders = this.languageClient
-		// .workspaceFolders();
-		// try {
-		// List<WorkspaceFolder> workspaceFolders = futureWorkspaceFolders.get();
-		// for (WorkspaceFolder workspaceFolder : workspaceFolders) {
-		// List<AcceleoTextDocument> acceleoTextDocuments = this.server.loadAllAcceleoDocumentsIn(
-		// workspaceFolder.getUri());
-		// for (AcceleoTextDocument candidateAcceleoDocument : acceleoTextDocuments) {
-		// if (documentDefinesModule(candidateAcceleoDocument, definedModule)) {
-		// definingTextDocument = candidateAcceleoDocument;
-		// }
-		// }
-		// }
-		// } catch (InterruptedException | ExecutionException exception) {
-		// throw new RuntimeException(exception);
-		// }
-		// }
-
 		List<AcceleoTextDocument> allTextDocuments = this.server.getWorkspace().getAllTextDocuments();
 		for (AcceleoTextDocument candidate : allTextDocuments) {
 			if (documentDefinesModule(candidate, definedModule)) {