Fixed: [ Issue 52 ] Add content-assist for message options
https://code.google.com/p/protobuf-dt/issues/detail?id=52
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 503b345..5e85bcc 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
@@ -75,11 +75,13 @@
@Override public void completeOption_Name(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
- EObject container = model.eContainer();
- if (container instanceof Protobuf) {
+ if (model instanceof Option) {
proposeCommonFileOptions(context, acceptor);
return;
}
+ if (model instanceof Message) {
+ proposeCommonMessageOptions(context, acceptor);
+ }
}
private void proposeCommonFileOptions(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
@@ -99,11 +101,24 @@
}
}
+ 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);
+ }
+ }
+
@Override public void completeOption_Value(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
Option option = (Option) model;
Descriptor descriptor = descriptorProvider.get();
Property fileOption = descriptor.lookupFileOption(option.getName());
+ if (fileOption == null) fileOption = descriptor.lookupMessageOption(option.getName());
if (fileOption == null) return;
if (descriptor.isOptimizeForOption(option)) {
proposeAndAccept(descriptor.optimizedMode(), context, acceptor);
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Descriptor.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Descriptor.java
index a113563..50d770c 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Descriptor.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Descriptor.java
@@ -85,6 +85,11 @@
.append(" optional bool py_generic_services = 18 [default=false];")
.append(" extensions 1000 to max;")
.append("}")
+ .append("message MessageOptions {")
+ .append(" optional bool message_set_wire_format = 1 [default=false];")
+ .append(" optional bool no_standard_descriptor_accessor = 2 [default=false];")
+ .append(" extensions 1000 to max;")
+ .append("}")
.append("message FieldOptions {")
.append(" optional CType ctype = 1 [default = STRING];")
.append(" enum CType {")
@@ -102,6 +107,7 @@
private void initContents() {
for (Message m : getAllContentsOfType(root, Message.class)) {
if (isFileOptionsMessage(m)) initFileOptions(m);
+ else if (isMessageOptionsMessage(m)) initMessageOptions(m);
else if (isFieldOptionsMessage(m)) initFieldOptions(m);
}
}
@@ -110,6 +116,10 @@
return "FileOptions".equals(m.getName());
}
+ private boolean isMessageOptionsMessage(Message m) {
+ return "MessageOptions".equals(m.getName());
+ }
+
private boolean isFieldOptionsMessage(Message m) {
return "FieldOptions".equals(m.getName());
}
@@ -131,6 +141,19 @@
addOption(FILE, p);
}
+ private void initMessageOptions(Message messageOptionsMessage) {
+ for (MessageElement e : messageOptionsMessage.getElements()) {
+ if (e instanceof Property) {
+ addMessageOption((Property) e);
+ continue;
+ }
+ }
+ }
+
+ private void addMessageOption(Property p) {
+ addOption(MESSAGE, p);
+ }
+
private void initFieldOptions(Message fieldOptionsMessage) {
for (MessageElement e : fieldOptionsMessage.getElements()) {
if (e instanceof Property) {
@@ -201,6 +224,27 @@
}
/**
+ * Returns all the message-level options available. These are the options defined in
+ * {@code google/protobuf/descriptor.proto} (more details can be found
+ * <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
+ * @return all the message-level options available.
+ */
+ public Collection<Property> messageOptions() {
+ return optionsOfType(MESSAGE);
+ }
+
+ /**
+ * Looks up a message-level option per name. Message-level options are defined in
+ * {@code google/protobuf/descriptor.proto} (more details can be found <a
+ * href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
+ * @param name the name of the option to look for.
+ * @return the option whose name matches the given one or {@code null} if a matching option is not found.
+ */
+ public Property lookupMessageOption(String name) {
+ return lookupOption(MESSAGE, name);
+ }
+
+ /**
* Returns all the field-level options available. These are the options defined in
* {@code google/protobuf/descriptor.proto} (more details can be found
* <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
index ab8ab3a..0eb4701 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
@@ -9,5 +9,5 @@
package com.google.eclipse.protobuf.scoping;
enum OptionType {
- FILE, FIELD;
+ FILE, MESSAGE, FIELD;
}
\ No newline at end of file