In progress: [Issue 94] Importing "google/protobuf/descriptor.proto"
does not work.

Got everything working with 'integration with protoc' disabled. What is
left is to tell protoc where to find descriptor.proto. Most likely in a
preference.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
index 59a0775..237a017 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
@@ -23,6 +23,7 @@
 
 import com.google.eclipse.protobuf.protobuf.Import;
 import com.google.eclipse.protobuf.ui.util.Resources;
+import com.google.eclipse.protobuf.util.Imports;
 import com.google.inject.Inject;
 
 /**
@@ -38,6 +39,7 @@
   private static final char QUOTE = '\"';
 
   @Inject private EObjectAtOffsetHelper eObjectAtOffsetHelper;
+  @Inject private Imports imports;
   @Inject private Resources resources;
 
   @Override public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region,
@@ -57,13 +59,15 @@
       public IHyperlink[] exec(XtextResource resource) {
         EObject resolved = eObjectAtOffsetHelper.resolveElementAt(resource, region.getOffset());
         if (!(resolved instanceof Import)) return NO_HYPERLINKS;
+        Import anImport = (Import) resolved;
+        if (imports.isImportingProtoDescriptor(anImport)) return NO_HYPERLINKS;
         IRegion importUriRegion;
         try {
           importUriRegion = importUriRegion(document, region.getOffset());
         } catch (BadLocationException e) {
           return NO_HYPERLINKS;
         }
-        String importUri = ((Import) resolved).getImportURI();
+        String importUri = anImport.getImportURI();
         IHyperlink hyperlink = new ImportHyperlink(createURI(importUri), importUriRegion, resources);
         return new IHyperlink[] { hyperlink };
       }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2 b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
index 492f4f0..cf43ef8 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
@@ -66,7 +66,7 @@
 
 			// java-based API for validation 
 			fragment = validation.JavaValidatorFragment {
-				composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
+				// composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
 				composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
 				// registerForImportedPackages = true
 			}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
index a4eb463..f1310a3 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
@@ -12,25 +12,26 @@
 import static com.google.eclipse.protobuf.scoping.OptionType.*;
 import static com.google.eclipse.protobuf.util.Closeables.close;
 import static com.google.eclipse.protobuf.util.Encodings.UTF_8;
-import static java.util.Collections.unmodifiableCollection;
+import static java.util.Collections.*;
 import static org.eclipse.xtext.EcoreUtil2.*;
 import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Enum;
-import com.google.eclipse.protobuf.util.*;
-import com.google.inject.Inject;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.xtext.nodemodel.INode;
-import org.eclipse.xtext.parser.*;
-import org.eclipse.xtext.resource.XtextResource;
-
 import java.io.*;
 import java.net.URL;
 import java.util.*;
 
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.parser.IParseResult;
+import org.eclipse.xtext.parser.IParser;
+import org.eclipse.xtext.resource.XtextResource;
+
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.eclipse.protobuf.util.ModelNodes;
+import com.google.inject.Inject;
+
 /**
  * Contains the elements from descriptor.proto (provided with protobuf's library.)
  *
@@ -38,8 +39,11 @@
  */
 public class ProtoDescriptor {
 
+  /** Path of proto.descriptor to use in imports. */
+  public static final String PATH = "google/protobuf/descriptor.proto";
+
   private static final Map<String, OptionType> OPTION_DEFINITION_BY_NAME = new HashMap<String, OptionType>();
-  
+
   static {
     OPTION_DEFINITION_BY_NAME.put("FileOptions", FILE);
     OPTION_DEFINITION_BY_NAME.put("MessageOptions", MESSAGE);
@@ -47,7 +51,8 @@
     OPTION_DEFINITION_BY_NAME.put("EnumOptions", ENUM);
     OPTION_DEFINITION_BY_NAME.put("MethodOptions", METHOD);
   }
-  
+
+  private final List<Type> allTypes = new ArrayList<Type>();
   private final Map<OptionType, Map<String, Property>> optionsByType = new HashMap<OptionType, Map<String, Property>>();
   private final Map<String, Enum> enumsByName = new HashMap<String, Enum>();
 
@@ -92,7 +97,10 @@
   }
 
   private void initContents() {
-    for (Message m : getAllContentsOfType(root, Message.class)) {
+    allTypes.addAll(getAllContentsOfType(root, Type.class));
+    for (Type t : allTypes) {
+      if (!(t instanceof Message)) continue;
+      Message m = (Message) t;
       OptionType type = OPTION_DEFINITION_BY_NAME.get(m.getName());
       if (type == null) continue;
       initOptions(m, type);
@@ -141,7 +149,7 @@
   public Property lookupOption(String name) {
     return lookupOption(name, FILE, MESSAGE, ENUM, METHOD);
   }
-  
+
   private Property lookupOption(String name, OptionType...types) {
     for (OptionType type : types) {
       Property p = lookupOption(name, type);
@@ -230,4 +238,12 @@
     String typeName = node.getText();
     return (isEmpty(typeName)) ? null : enumsByName.get(typeName.trim());
   }
+
+  /**
+   * Returns all types in descriptor.proto.
+   * @return all types in descriptor.proto.
+   */
+  public List<Type> allTypes() {
+    return unmodifiableList(allTypes);
+  }
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java
index 4fdd459..aed9f58 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java
@@ -44,7 +44,6 @@
       // anImport.setImportURI(originalUri);
       return applied;
     }
-    if (from instanceof Import) resolveImportUri((Import) from);
     return super.apply(from);
   }
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
index 8ed5113..f8f4d35 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
@@ -17,11 +17,16 @@
 
 import java.util.*;
 
-import org.eclipse.emf.common.util.*;
-import org.eclipse.emf.ecore.*;
-import org.eclipse.emf.ecore.resource.*;
-import org.eclipse.xtext.naming.*;
-import org.eclipse.xtext.resource.*;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.resource.XtextResource;
 import org.eclipse.xtext.scoping.IScope;
 import org.eclipse.xtext.scoping.impl.*;
 
@@ -50,6 +55,7 @@
   @Inject private LocalNamesProvider localNamesProvider;
   @Inject private ImportedNamesProvider importedNamesProvider;
   @Inject private PackageResolver packageResolver;
+  @Inject private Imports imports;
 
   @SuppressWarnings("unused")
   IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
@@ -104,15 +110,19 @@
   }
 
   private <T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
-    List<Import> imports = finder.importsIn(root);
-    if (imports.isEmpty()) return emptyList();
-    return importedTypes(imports, finder.packageOf(root), targetType);
+    List<Import> allImports = finder.importsIn(root);
+    if (allImports.isEmpty()) return emptyList();
+    return importedTypes(allImports, finder.packageOf(root), targetType);
   }
 
-  private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> imports, Package aPackage,
+  private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> allImports, Package aPackage,
       Class<T> targetType) {
     List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
-    for (Import anImport : imports) {
+    for (Import anImport : allImports) {
+      if (imports.isImportingProtoDescriptor(anImport)) {
+        descriptions.addAll(allBuiltInTypes(targetType));
+        continue;
+      }
       Resource importedResource = importedResourceFrom(anImport);
       Protobuf importedRoot = rootElementOf(importedResource);
       descriptions.addAll(publicImportedTypes(importedRoot, targetType));
@@ -125,10 +135,24 @@
     return descriptions;
   }
 
+  private <T extends Type> Collection<IEObjectDescription> allBuiltInTypes(Class<T> targetType) {
+    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+    ProtoDescriptor descriptor = descriptorProvider.get();
+    for (Type t : descriptor.allTypes()) {
+      if (!targetType.isInstance(t)) continue;
+      T type = targetType.cast(t);
+      descriptions.addAll(fullyQualifiedNamesOf(type));
+      for (QualifiedName name : importedNamesProvider.namesOf(type)) {
+        descriptions.add(create(name, type));
+      }
+    }
+    return descriptions;
+  }
+
   private <T extends Type> Collection<IEObjectDescription> publicImportedTypes(Protobuf root, Class<T> targetType) {
-    List<Import> imports = finder.publicImportsIn(root);
-    if (imports.isEmpty()) return emptyList();
-    return importedTypes(imports, finder.packageOf(root), targetType);
+    List<Import> allImports = finder.publicImportsIn(root);
+    if (allImports.isEmpty()) return emptyList();
+    return importedTypes(allImports, finder.packageOf(root), targetType);
   }
 
   private Resource importedResourceFrom(Import anImport) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java
new file mode 100644
index 0000000..c245f9d
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java
@@ -0,0 +1,33 @@
+/*
+ * 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.util;
+
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.scoping.ProtoDescriptor;
+import com.google.inject.Singleton;
+
+/**
+ * Utility methods related to imports.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton
+public class Imports {
+
+  /**
+   * Indicates whether the URL of the given import is equal to the path of descriptor.proto.
+   * @param anImport the import to check.
+   * @return {@code true} if the URL of the given import is equal to the path of descriptor.proto, {@code false}
+   * otherwise.
+   */
+  public boolean isImportingProtoDescriptor(Import anImport) {
+    if (anImport == null) return false;
+    return ProtoDescriptor.PATH.equals(anImport.getImportURI());
+  }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
index ce147b0..65833f7 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
@@ -15,7 +15,8 @@
 
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.eclipse.xtext.naming.QualifiedName;
 import org.eclipse.xtext.scoping.impl.ImportUriResolver;
 import org.eclipse.xtext.validation.Check;
 
@@ -32,6 +33,7 @@
   @Inject private FieldOptions fieldOptions;
   @Inject private ImportUriResolver uriResolver;
   @Inject private IQualifiedNameProvider qualifiedNameProvider;
+  @Inject private Imports imports;
   @Inject private Properties properties;
 
   @Check public void checkDefaultValueType(FieldOption option) {
@@ -58,6 +60,8 @@
   }
 
   private boolean isResolved(Import anImport) {
+    // global proto file, always available
+    if (imports.isImportingProtoDescriptor(anImport)) return true;
     String importUri = anImport.getImportURI();
     if (!isEmpty(importUri)) {
       URI uri = URI.createURI(importUri);