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