Fixed: [ Issue 70 ] Validation doesn't start until editing
https://code.google.com/p/protobuf-dt/issues/detail?id=70

Validation now happens every time an editor is activated.

diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
index 349492d..89845d8 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
@@ -12,6 +12,7 @@
 import static org.eclipse.ui.PlatformUI.isWorkbenchRunning;
 
 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.ui.*;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 import org.eclipse.xtext.ui.LanguageSpecific;
@@ -27,12 +28,14 @@
 import com.google.eclipse.protobuf.ui.editor.hyperlinking.ProtobufHyperlinkDetector;
 import com.google.eclipse.protobuf.ui.editor.model.ProtobufDocumentProvider;
 import com.google.eclipse.protobuf.ui.editor.syntaxcoloring.ProtobufSemanticHighlightingCalculator;
+import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
 import com.google.eclipse.protobuf.ui.outline.*;
 import com.google.eclipse.protobuf.ui.preferences.PreferenceStoreAccess;
 import com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.scoping.FileUriResolver;
-import com.google.inject.Binder;
+import com.google.eclipse.protobuf.ui.validation.ValidateOnActivation;
+import com.google.inject.*;
 
 /**
  * Use this class to register components to be used within the IDE.
@@ -42,9 +45,15 @@
 public class ProtobufUiModule extends AbstractProtobufUiModule {
 
   public static final String PLUGIN_ID = "com.google.eclipse.protobuf.ui";
-
+  
   public ProtobufUiModule(AbstractUIPlugin plugin) {
     super(plugin);
+    setValidationTrigger(PlatformUI.getWorkbench().getActiveWorkbenchWindow(), plugin);
+  }
+
+  private void setValidationTrigger(IWorkbenchWindow w, AbstractUIPlugin plugin) {
+    if (w == null || !(plugin instanceof ProtobufActivator)) return;
+    w.getPartService().addPartListener(new ValidateOnActivation());
   }
 
   @Override public Class<? extends IContentOutlinePage> bindIContentOutlinePage() {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
new file mode 100644
index 0000000..f949ea3
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ * 
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.validation;
+
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
+import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
+
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.util.ModelNodes;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.ui.*;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
+import org.eclipse.xtext.ui.editor.XtextEditor;
+import org.eclipse.xtext.ui.editor.model.*;
+import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+
+import java.util.List;
+
+/**
+ * Validates a .proto file when it is opened or activated.
+ * 
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ValidateOnActivation implements IPartListener2 {
+
+  private final ModelNodes nodes = new ModelNodes();
+  
+  public void partActivated(IWorkbenchPartReference partRef) {
+    final XtextEditor editor = protoEditorFrom(partRef);
+    if (editor == null) return;
+    validate(editor);
+  }
+  
+  private XtextEditor protoEditorFrom(IWorkbenchPartReference partRef) {
+    XtextEditor editor = xtextEditorFrom(partRef);
+    if (editor == null) return null;
+    if (!"com.google.eclipse.protobuf.Protobuf".equals(editor.getLanguageName())) return null;
+    if (!(editor.getEditorInput() instanceof FileEditorInput)) return null;
+    return editor;
+  }
+  
+  private XtextEditor xtextEditorFrom(IWorkbenchPartReference partRef) {
+    IWorkbenchPage page = partRef.getPage();
+    if (page == null) return null;
+    IEditorPart activeEditor = page.getActiveEditor();
+    return (activeEditor instanceof XtextEditor) ? (XtextEditor) activeEditor : null;
+  }
+
+  private void validate(XtextEditor editor) {
+    final IXtextDocument document = editor.getDocument();
+    if (!(document instanceof XtextDocument)) return;
+    document.readOnly(new IUnitOfWork<Void, XtextResource>() {
+      public java.lang.Void exec(XtextResource resource) throws Exception {
+        EObject root = resource.getParseResult().getRootASTElement();
+        resetImports(root);
+        resource.getLinker().linkModel(root, new ListBasedDiagnosticConsumer());
+        ((XtextDocument) document).checkAndUpdateAnnotations();
+        return null;
+      }
+    });
+  }
+
+  private void resetImports(EObject root) {
+    List<Import> imports = getAllContentsOfType(root, Import.class);
+    for (Import anImport : imports) resetUri(anImport);
+  }
+
+  private void resetUri(Import anImport) {
+    String uri = uriAsEnteredInEditor(anImport);
+    if (uri == null) return;
+    anImport.setImportURI(uri);
+  }
+  
+  private String uriAsEnteredInEditor(Import anImport) {
+    INode node = nodes.firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
+    if (node == null) return null;
+    String text = node.getText();
+    if (text == null) return null;
+    return text.substring(1, text.length() - 1);
+  }
+
+  public void partBroughtToTop(IWorkbenchPartReference partRef) {}
+
+  public void partClosed(IWorkbenchPartReference partRef) {}
+
+  public void partDeactivated(IWorkbenchPartReference partRef) {}
+
+  public void partOpened(IWorkbenchPartReference partRef) {}
+
+  public void partHidden(IWorkbenchPartReference partRef) {}
+
+  public void partVisible(IWorkbenchPartReference partRef) {}
+
+  public void partInputChanged(IWorkbenchPartReference partRef) {}
+}