Working on supporting pluggable descriptor.proto definitions.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
index 0bdd093..8374bba 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -15,8 +15,7 @@
import static java.lang.String.valueOf;
import static java.util.Collections.emptyList;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
@@ -30,10 +29,11 @@
import com.google.eclipse.protobuf.protobuf.*;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.scoping.*;
-import com.google.eclipse.protobuf.ui.grammar.CommonKeyword;
+import com.google.eclipse.protobuf.ui.grammar.*;
import com.google.eclipse.protobuf.ui.grammar.CompoundElement;
import com.google.eclipse.protobuf.ui.labeling.Images;
import com.google.eclipse.protobuf.ui.util.*;
+import com.google.eclipse.protobuf.ui.util.Properties;
import com.google.eclipse.protobuf.util.ProtobufElementFinder;
import com.google.inject.Inject;
@@ -92,34 +92,15 @@
}
return false;
}
-
+
private void proposeCommonFileOptions(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- for (Property fileOption : descriptorProvider.get().fileOptions()) {
- String displayString = fileOption.getName();
- String proposalText = displayString + SPACE + EQUAL + SPACE;
- boolean isStringOption = properties.isString(fileOption);
- if (isStringOption)
- proposalText = proposalText + EMPTY_STRING + SEMICOLON;
- ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, context);
- if (isStringOption && proposal instanceof ConfigurableCompletionProposal) {
- // set cursor between the proposal's quotes
- ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
- configurable.setCursorPosition(proposalText.length() - 2);
- }
- acceptor.accept(proposal);
- }
+ for (Property option : descriptorProvider.get().fileOptions())
+ proposeOption(option, context, acceptor);
}
private void proposeCommonMessageOptions(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- for (Property messageOption : descriptorProvider.get().messageOptions()) {
- String displayString = messageOption.getName();
- String proposalText = displayString + SPACE + EQUAL + SPACE;
- boolean isBooleanOption = properties.isBool(messageOption);
- if (isBooleanOption)
- proposalText = proposalText + TRUE;
- ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, context);
- acceptor.accept(proposal);
- }
+ for (Property option : descriptorProvider.get().messageOptions())
+ proposeOption(option, context, acceptor);
}
@Override public void completeOption_Value(EObject model, Assignment assignment, ContentAssistContext context,
@@ -287,7 +268,7 @@
private Property extractPropertyFrom(ContentAssistContext context) {
return extractElementFromContext(context, Property.class);
}
-
+
private <T> T extractElementFromContext(ContentAssistContext context, Class<T> type) {
EObject model = context.getCurrentModel();
// this is most likely a bug in Xtext:
@@ -373,17 +354,13 @@
private Field extractFieldFrom(ContentAssistContext context) {
return extractElementFromContext(context, Field.class);
}
-
+
private void proposeCommonFieldOptions(Field field, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
List<String> options = existingFieldOptionNames(field);
- for (Property fieldOption : descriptorProvider.get().fieldOptions()) {
- String optionName = fieldOption.getName();
+ for (Property option : descriptorProvider.get().fieldOptions()) {
+ String optionName = option.getName();
if (options.contains(optionName) || ("packed".equals(optionName) && !canBePacked(field))) continue;
- String proposalText = optionName + SPACE + EQUAL + SPACE;
- boolean isBooleanOption = properties.isBool(fieldOption);
- if (isBooleanOption) proposalText = proposalText + TRUE;
- ICompletionProposal proposal = createCompletionProposal(proposalText, context);
- acceptor.accept(proposal);
+ proposeOption(option, context, acceptor);
}
}
@@ -401,6 +378,24 @@
return properties.isPrimitive(property) && REPEATED.equals(property.getModifier());
}
+ private void proposeOption(Property option, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+ String displayString = option.getName();
+ String proposalText = displayString + SPACE + EQUAL + SPACE;
+ boolean isStringOption = properties.isString(option);
+ if (isStringOption) {
+ proposalText = proposalText + EMPTY_STRING + SEMICOLON;
+ } else if (properties.isBool(option)) {
+ proposalText = proposalText + TRUE;
+ }
+ ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, context);
+ if (isStringOption && proposal instanceof ConfigurableCompletionProposal) {
+ // set cursor between the proposal's quotes
+ ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
+ configurable.setCursorPosition(proposalText.length() - 2);
+ }
+ acceptor.accept(proposal);
+ }
+
@Override public void completeFieldOption_Value(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
FieldOption option = (FieldOption) model;
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IProtoDescriptor.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IProtoDescriptor.java
index c8c6482..4560359 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IProtoDescriptor.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IProtoDescriptor.java
@@ -8,14 +8,14 @@
*/
package com.google.eclipse.protobuf.scoping;
+import java.util.Collection;
+
import com.google.eclipse.protobuf.protobuf.*;
import com.google.eclipse.protobuf.protobuf.Enum;
-import java.util.Collection;
-
/**
* Contains the elements from descriptor.proto (provided with protobuf's library.)
- *
+ *
* @author alruiz@google.com (Alex Ruiz)
*/
public interface IProtoDescriptor {
@@ -63,8 +63,8 @@
public abstract Property lookupFieldOption(String name);
/**
- * Returns the enum type of the given option, only if the given option is defined in
- * {@code google/protobuf/descriptor.proto} and its type an enum (more details can be found <a
+ * Returns the enum type of the given option, only if the given option is defined in
+ * {@code google/protobuf/descriptor.proto} and its type is enum (more details can be found <a
* href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
* @param option the given option.
* @return the enum type of the given option or {@code null} if the type of the given option is not enum.
@@ -72,8 +72,8 @@
public abstract Enum enumTypeOf(Option option);
/**
- * Returns the enum type of the given option, only if the given option is defined in
- * {@code google/protobuf/descriptor.proto} and its type an enum (more details can be found <a
+ * Returns the enum type of the given option, only if the given option is defined in
+ * {@code google/protobuf/descriptor.proto} and its type is enum (more details can be found <a
* href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
* @param option the given option.
* @return the enum type of the given option or {@code null} if the type of the given option is not enum.
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 6e4b7a8..2b9a399 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
@@ -15,16 +15,16 @@
import static org.eclipse.xtext.EcoreUtil2.*;
import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Enum;
-import com.google.inject.Inject;
+import java.io.*;
+import java.net.URL;
+import java.util.*;
import org.eclipse.xtext.parser.*;
import org.eclipse.xtext.resource.XtextResource;
-import java.io.*;
-import java.net.URL;
-import java.util.*;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.inject.Inject;
/**
* Contains the elements from descriptor.proto (provided with protobuf's library.)
@@ -36,10 +36,9 @@
private static final String DESCRIPTOR_URI = "platform:/plugin/com.google.eclipse.protobuf/descriptor.proto";
private final Map<OptionType, Map<String, Property>> options = new HashMap<OptionType, Map<String, Property>>();
-
+ private final Map<String, Enum> enums = new HashMap<String, Enum>();
+
private Protobuf root;
- private Enum optimizedMode;
- private Enum cType;
@Inject public ProtoDescriptor(IParser parser) {
addOptionTypes();
@@ -52,8 +51,9 @@
resource.getContents().add(root);
resolveLazyCrossReferences(resource, NullImpl);
initContents();
- } catch (IOException e) {
- throw new IllegalStateException("Unable to parse descriptor.proto", e);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw new IllegalStateException("Unable to parse descriptor.proto", t);
} finally {
close(reader);
}
@@ -63,7 +63,7 @@
for (OptionType type : OptionType.values())
options.put(type, new LinkedHashMap<String, Property>());
}
-
+
private static InputStream globalScopeContents() throws IOException {
URL url = new URL(DESCRIPTOR_URI);
return url.openConnection().getInputStream();
@@ -76,7 +76,7 @@
else if (isFieldOptionsMessage(m)) initFieldOptions(m);
}
}
-
+
private boolean isFileOptionsMessage(Message m) {
return "FileOptions".equals(m.getName());
}
@@ -96,12 +96,12 @@
continue;
}
if (isEnumWithName(e, "OptimizeMode")) {
- optimizedMode = (Enum) e;
+ enums.put("optimize_for", (Enum) e);
continue;
}
}
}
-
+
private void addFileOption(Property p) {
addOption(FILE, p);
}
@@ -114,7 +114,7 @@
}
}
}
-
+
private void addMessageOption(Property p) {
addOption(MESSAGE, p);
}
@@ -126,7 +126,7 @@
continue;
}
if (isEnumWithName(e, "CType")) {
- cType = (Enum) e;
+ enums.put("ctype", (Enum) e);
continue;
}
}
@@ -135,22 +135,22 @@
private void addFieldOption(Property p) {
addOption(FIELD, p);
}
-
+
private void addOption(OptionType type, Property p) {
if (shouldIgnore(p)) return;
options.get(type).put(p.getName(), p);
}
-
+
private boolean shouldIgnore(Property property) {
return "uninterpreted_option".equals(property.getName());
}
-
+
private boolean isEnumWithName(MessageElement e, String name) {
if (!(e instanceof Enum)) return false;
Enum anEnum = (Enum) e;
return name.equals(anEnum.getName());
}
-
+
/** {@inheritDoc} */
public Collection<Property> fileOptions() {
return optionsOfType(FILE);
@@ -176,35 +176,23 @@
private Collection<Property> optionsOfType(OptionType type) {
return unmodifiableCollection(options.get(type).values());
}
-
+
/** {@inheritDoc} */
public Property lookupFieldOption(String name) {
return lookupOption(FIELD, name);
}
-
+
private Property lookupOption(OptionType type, String name) {
return options.get(type).get(name);
}
/** {@inheritDoc} */
public Enum enumTypeOf(Option option) {
- if (isOptimizeForOption(option)) return optimizedMode;
- return null;
- }
-
- private boolean isOptimizeForOption(Option option) {
- if (option == null) return false;
- return "optimize_for".equals(option.getName());
+ return enums.get(option.getName());
}
/** {@inheritDoc} */
public Enum enumTypeOf(FieldOption option) {
- if (isCTypeOption(option)) return cType;
- return null;
- }
-
- private boolean isCTypeOption(FieldOption option) {
- if (option == null) return false;
- return "ctype".equals(option.getName());
+ return enums.get(option.getName());
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
index 4de2810..6734b2d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
@@ -8,10 +8,10 @@
*/
package com.google.eclipse.protobuf.scoping;
-import com.google.inject.*;
-
import org.eclipse.xtext.parser.IParser;
+import com.google.inject.*;
+
/**
* Provider of a singleton instance of <code>{@link ProtoDescriptor}</code>.
*