In progress: [Issue 164] Validate that the default value of a field
matches the type of such field.
diff --git a/com.google.eclipse.protobuf.feature/feature.xml b/com.google.eclipse.protobuf.feature/feature.xml
index 7c1e61f..bf5e092 100644
--- a/com.google.eclipse.protobuf.feature/feature.xml
+++ b/com.google.eclipse.protobuf.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="com.google.eclipse.protobuf"
label="%featureName"
- version="1.0.11.qualifier"
+ version="1.1.0.qualifier"
provider-name="%providerName">
<description url="https://code.google.com/p/protobuf-dt/">
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isBool_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isBool_Test.java
similarity index 82%
rename from com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isBool_Test.java
rename to com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isBool_Test.java
index 4959897..0a43f41 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isBool_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isBool_Test.java
@@ -18,18 +18,18 @@
import com.google.eclipse.protobuf.protobuf.MessageField;
/**
- * Tests for <code>{@link Fields#isBool(MessageField)}</code>.
+ * Tests for <code>{@link MessageFields#isBool(MessageField)}</code>.
*
* @author alruiz@google.com (Alex Ruiz)
*/
-public class Properties_isBool_Test {
+public class MessageFields_isBool_Test {
@Rule public XtextRule xtext = createWith(unitTestSetup());
- private Fields properties;
+ private MessageFields fields;
@Before public void setUp() {
- properties = xtext.getInstanceOf(Fields.class);
+ fields = xtext.getInstanceOf(MessageFields.class);
}
// syntax = "proto2";
@@ -39,7 +39,7 @@
// }
@Test public void should_return_true_if_field_is_bool() {
MessageField field = xtext.find("code", MessageField.class);
- assertTrue(properties.isBool(field));
+ assertTrue(fields.isBool(field));
}
// syntax = "proto2";
@@ -49,6 +49,6 @@
// }
@Test public void should_return_false_if_property_is_not_bool() {
MessageField field = xtext.find("name", MessageField.class);
- assertFalse(properties.isBool(field));
+ assertFalse(fields.isBool(field));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isPrimitive_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isPrimitive_Test.java
similarity index 75%
rename from com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isPrimitive_Test.java
rename to com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isPrimitive_Test.java
index ec37bbf..c1eef68 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isPrimitive_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isPrimitive_Test.java
@@ -21,18 +21,18 @@
import com.google.eclipse.protobuf.protobuf.MessageField;
/**
- * Tests for <code>{@link Fields#isPrimitive(MessageField)}</code>.
+ * Tests for <code>{@link MessageFields#isPrimitive(MessageField)}</code>.
*
* @author alruiz@google.com (Alex Ruiz)
*/
-public class Properties_isPrimitive_Test {
+public class MessageFields_isPrimitive_Test {
@Rule public XtextRule xtext = createWith(unitTestSetup());
- private Fields properties;
+ private MessageFields fields;
@Before public void setUp() {
- properties = xtext.getInstanceOf(Fields.class);
+ fields = xtext.getInstanceOf(MessageFields.class);
}
// syntax = "proto2";
@@ -50,9 +50,9 @@
// optional bool bool_1 = 10;
// }
@Test public void should_return_true_if_field_is_primitive() {
- List<MessageField> fields = getAllContentsOfType(xtext.root(), MessageField.class);
- for (MessageField field : fields)
- assertTrue(properties.isPrimitive(field));
+ List<MessageField> allFields = getAllContentsOfType(xtext.root(), MessageField.class);
+ for (MessageField field : allFields)
+ assertTrue(fields.isPrimitive(field));
}
// syntax = "proto2";
@@ -67,8 +67,8 @@
// optional string name = 1;
// }
@Test public void should_return_false_if_field_is_not_primitive() {
- List<MessageField> fields = getAllContentsOfType(xtext.root(), MessageField.class);
- for (MessageField p : fields)
- assertFalse(properties.isPrimitive(p));
+ List<MessageField> allFields = getAllContentsOfType(xtext.root(), MessageField.class);
+ for (MessageField p : allFields)
+ assertFalse(fields.isPrimitive(p));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isString_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isString_Test.java
similarity index 81%
rename from com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isString_Test.java
rename to com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isString_Test.java
index 0270976..7c8a2c1 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_isString_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_isString_Test.java
@@ -18,18 +18,18 @@
import com.google.eclipse.protobuf.protobuf.MessageField;
/**
- * Tests for <code>{@link Fields#isString(MessageField)}</code>.
+ * Tests for <code>{@link MessageFields#isString(MessageField)}</code>.
*
* @author alruiz@google.com (Alex Ruiz)
*/
-public class Properties_isString_Test {
+public class MessageFields_isString_Test {
@Rule public XtextRule xtext = createWith(unitTestSetup());
- private Fields properties;
+ private MessageFields fields;
@Before public void setUp() {
- properties = xtext.getInstanceOf(Fields.class);
+ fields = xtext.getInstanceOf(MessageFields.class);
}
// syntax = "proto2";
@@ -39,7 +39,7 @@
// }
@Test public void should_return_true_if_field_is_string() {
MessageField field = xtext.find("name", MessageField.class);
- assertTrue(properties.isString(field));
+ assertTrue(fields.isString(field));
}
// syntax = "proto2";
@@ -49,6 +49,6 @@
// }
@Test public void should_return_false_if_field_is_not_string() {
MessageField field = xtext.find("code", MessageField.class);
- assertFalse(properties.isString(field));
+ assertFalse(fields.isString(field));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_typeNameOf_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_typeNameOf_Test.java
similarity index 81%
rename from com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_typeNameOf_Test.java
rename to com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_typeNameOf_Test.java
index c573453..cc251bf 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Properties_typeNameOf_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_typeNameOf_Test.java
@@ -19,18 +19,18 @@
import com.google.eclipse.protobuf.protobuf.MessageField;
/**
- * Tests for <code>{@link Fields#typeNameOf(MessageField)}</code>.
+ * Tests for <code>{@link MessageFields#typeNameOf(MessageField)}</code>.
*
* @author alruiz@google.com (Alex Ruiz)
*/
-public class Properties_typeNameOf_Test {
+public class MessageFields_typeNameOf_Test {
@Rule public XtextRule xtext = createWith(unitTestSetup());
- private Fields properties;
+ private MessageFields fields;
@Before public void setUp() {
- properties = xtext.getInstanceOf(Fields.class);
+ fields = xtext.getInstanceOf(MessageFields.class);
}
// syntax = "proto2";
@@ -40,7 +40,7 @@
// }
@Test public void should_return_name_of_scalar() {
MessageField field = xtext.find("name", MessageField.class);
- assertThat(properties.typeNameOf(field), equalTo("string"));
+ assertThat(fields.typeNameOf(field), equalTo("string"));
}
// syntax = "proto2";
@@ -55,6 +55,6 @@
// }
@Test public void should_return_name_of_type() {
MessageField field = xtext.find("number", MessageField.class);
- assertThat(properties.typeNameOf(field), equalTo("PhoneNumber"));
+ assertThat(fields.typeNameOf(field), equalTo("PhoneNumber"));
}
}
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 9174060..a0c3d35 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
@@ -47,7 +47,6 @@
*/
public class ProtobufProposalProvider extends AbstractProtobufProposalProvider {
-
@Inject private IEObjectDescriptionChooser descriptionChooser;
@Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private FieldOptions fieldOptions;
@@ -56,8 +55,8 @@
@Inject private IndexedElements indexedElements;
@Inject private PluginImageHelper imageHelper;
@Inject private Literals literals;
+ @Inject private MessageFields messageFields;
@Inject private Options options;
- @Inject private Fields properties;
@Override public void completeProtobuf_Syntax(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {}
@@ -83,7 +82,7 @@
}
}
- @Override public void completeMessageLink_Target(EObject model, Assignment assignment, ContentAssistContext context,
+ @Override public void completeMessageLink_Target(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
Collection<IEObjectDescription> scope = emptySet();
if (model instanceof MessageExtension) {
@@ -99,7 +98,7 @@
proposeAndAccept(d, image, context, acceptor);
}
}
-
+
@Override public void completeNativeOption_Source(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
@@ -185,7 +184,7 @@
private boolean isKeyword(EObject object, CommonKeyword keyword) {
return object instanceof Keyword && keyword.hasValue(((Keyword) object).getValue());
}
-
+
private void proposeEqualProto2(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
proposeAndAccept(EQUAL_PROTO2_IN_QUOTES, context, acceptor);
}
@@ -197,12 +196,12 @@
private boolean isBoolProposalValid(ContentAssistContext context) {
MessageField field = fieldFrom(context);
- return field != null && properties.isBool(field);
+ return field != null && messageFields.isBool(field);
}
private boolean isNanProposalValid(ContentAssistContext context) {
MessageField field = fieldFrom(context);
- return field != null && properties.mayBeNan(field);
+ return field != null && messageFields.mayBeNan(field);
}
private MessageField fieldFrom(ContentAssistContext context) {
@@ -230,7 +229,7 @@
if (OPTIONAL.equals(modifier)) {
CompoundElement display = DEFAULT_EQUAL_IN_BRACKETS;
int cursorPosition = display.indexOf(CLOSING_BRACKET);
- if (properties.isString(field)) {
+ if (messageFields.isString(field)) {
display = DEFAULT_EQUAL_STRING_IN_BRACKETS;
cursorPosition++;
}
@@ -266,13 +265,13 @@
field = (MessageField) model.eContainer();
}
if (field == null) return;
- if (!properties.isOptional(field)) return;
+ if (!messageFields.isOptional(field)) return;
Enum enumType = finder.enumTypeOf(field);
if (enumType != null) {
proposeAndAccept(enumType, context, acceptor);
}
}
-
+
@Override public void completeMessageField_Index(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
long index = indexedElements.calculateTagNumberOf((MessageField) model);
@@ -285,7 +284,7 @@
@Override public void completeMessageField_Name(EObject model, Assignment assignment, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
- String typeName = toFirstLower(properties.typeNameOf((MessageField) model));
+ String typeName = toFirstLower(messageFields.typeNameOf((MessageField) model));
int index = 1;
String name = typeName + index;
for (EObject o : model.eContainer().eContents()) {
@@ -343,10 +342,10 @@
ICompletionProposalAcceptor acceptor) {
if (!(e instanceof MessageField)) return;
MessageField field = (MessageField) e;
- if (!properties.isOptional(field) || existingOptionNames.contains(DEFAULT.toString())) return;
+ if (!messageFields.isOptional(field) || existingOptionNames.contains(DEFAULT.toString())) return;
CompoundElement display = DEFAULT_EQUAL;
int cursorPosition = display.charCount();
- if (properties.isString(field)) {
+ if (messageFields.isString(field)) {
display = DEFAULT_EQUAL_STRING;
cursorPosition++;
}
@@ -356,7 +355,7 @@
private boolean canBePacked(IndexedElement e) {
if (!(e instanceof MessageField)) return false;
MessageField field = (MessageField) e;
- return properties.isPrimitive(field) && REPEATED.equals(field.getModifier());
+ return messageFields.isPrimitive(field) && REPEATED.equals(field.getModifier());
}
private void proposeOption(MessageField optionSource, ContentAssistContext context,
@@ -373,14 +372,14 @@
}
acceptor.accept(proposal);
}
-
+
private Object defaultValueOf(MessageField field) {
- if (properties.isBool(field)) return TRUE;
- if (properties.isString(field)) return EMPTY_STRING;
+ if (messageFields.isBool(field)) return TRUE;
+ if (messageFields.isString(field)) return EMPTY_STRING;
return null;
}
-
- @Override public void completeDefaultValueFieldOption_Value(EObject model, Assignment assignment,
+
+ @Override public void completeDefaultValueFieldOption_Value(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
MessageField field = null;
if (model instanceof DefaultValueFieldOption) {
@@ -390,7 +389,7 @@
field = (MessageField) model;
}
if (field == null) return;
- if (!properties.isOptional(field)) return;
+ if (!messageFields.isOptional(field)) return;
proposeFieldValue(field, context, acceptor);
}
@@ -410,11 +409,11 @@
private boolean proposePrimitiveValues(MessageField field, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
- if (properties.isBool(field)) {
+ if (messageFields.isBool(field)) {
proposeBooleanValues(context, acceptor);
return true;
}
- if (properties.isString(field)) {
+ if (messageFields.isString(field)) {
proposeEmptyString(context, acceptor);
return true;
}
@@ -493,7 +492,7 @@
proposeAndAccept(scoping().allPossibleNormalFieldsOf(option), context, acceptor);
proposeExtensionFields(scoping().allPossibleExtensionFieldsOf(option), context, acceptor);
}
-
+
private void proposeExtensionFields(Collection<IEObjectDescription> scope, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
String format = "(%s)";
@@ -555,7 +554,7 @@
proposeAndAccept(enumType, context, acceptor);
}
}
-
+
private void proposeAndAccept(Enum enumType, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
Image image = imageHelper.getImage(images.imageFor(Literal.class));
for (Literal literal : getAllContentsOfType(enumType, Literal.class))
@@ -621,7 +620,7 @@
private Scoping scoping() {
return (ProtobufScopeProvider) super.getScopeProvider();
}
-
+
@Override public ICompletionProposal createCompletionProposal(String proposal, String displayString, Image image,
ContentAssistContext contentAssistContext) {
StyledString styled = null;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java
index 665b74a..579a71f 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java
@@ -12,13 +12,13 @@
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
import static org.eclipse.jface.viewers.StyledString.DECORATIONS_STYLER;
+import java.util.List;
+
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.xtext.nodemodel.INode;
-import java.util.List;
-
import com.google.eclipse.protobuf.model.util.*;
import com.google.eclipse.protobuf.naming.NameResolver;
import com.google.eclipse.protobuf.protobuf.*;
@@ -32,9 +32,9 @@
@Singleton public class Labels {
@Inject private NameResolver nameResolver;
+ @Inject private MessageFields messageFields;
@Inject private INodes nodes;
@Inject private Options options;
- @Inject private Fields properties;
public Object labelFor(Object o) {
if (o instanceof Extensions) {
@@ -70,7 +70,7 @@
}
return null;
}
-
+
private Object labelFor(Extensions extensions) {
StringBuilder builder = new StringBuilder();
EList<Range> ranges = extensions.getRanges();
@@ -86,7 +86,7 @@
}
return builder.toString();
}
-
+
private Object labelFor(Import anImport) {
INode node = nodes.firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
if (node == null) return anImport.getImportURI();
@@ -106,7 +106,7 @@
private Object labelFor(MessageField field) {
StyledString text = new StyledString(nameResolver.nameOf(field));
- String typeName = properties.typeNameOf(field);
+ String typeName = messageFields.typeNameOf(field);
if (typeName == null) typeName = "<unresolved reference>"; // TODO move to
// properties
// file
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/INodes.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/INodes.java
index b63c1ed..20debce 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/INodes.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/INodes.java
@@ -97,7 +97,7 @@
TerminalRule terminalRule = (TerminalRule) rule;
return "STRING".equals(terminalRule.getName());
}
-
+
/**
* Indicates whether the given node is a hidden leaf node.
* @param node the node to check.
@@ -107,4 +107,14 @@
if (!(node instanceof ILeafNode)) return false;
return ((ILeafNode) node).isHidden();
}
+
+ /**
+ * Returns the text of the given node, with leading and trailing whitespace omitted.
+ * @param node the given node.
+ * @return the text of the given node, with leading and trailing whitespace omitted.
+ */
+ public String textOf(INode node) {
+ String text = node.getText();
+ return (text == null) ? null : text.trim();
+ }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Fields.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java
similarity index 97%
rename from com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Fields.java
rename to com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java
index 8d5875c..1970a4a 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Fields.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java
@@ -16,12 +16,12 @@
import com.google.inject.*;
/**
- * Utility methods related to <code>{@link MessageField}</code>.
+ * Utility methods related to <code>{@link MessageField}</code>s.
*
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton
-public class Fields {
+public class MessageFields {
/**
* Indicates whether the modifier of the given field is <code>{@link Modifier#OPTIONAL}</code>.
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java
new file mode 100644
index 0000000..606cf00
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.validation;
+
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.FIELD_OPTION__VALUE;
+import static com.google.eclipse.protobuf.validation.Messages.*;
+
+import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.validation.*;
+
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class DataTypeValidator extends AbstractDeclarativeValidator {
+
+ @Override public void register(EValidatorRegistrar registrar) {}
+
+ @Inject private FieldOptions fieldOptions;
+ @Inject private IQualifiedNameProvider fqnProvider;
+ @Inject private MessageFields messageFields;
+ @Inject private ModelFinder modelFinder;
+ @Inject private INodes nodes;
+
+ @Check public void checkValueOfDefaultTypeMatchesFieldType(FieldOption option) {
+ if (fieldOptions.isDefaultValueOption(option)) {
+ MessageField field = (MessageField) option.eContainer();
+ INode nodeForValueFeature = nodes.firstNodeForFeature(option, FIELD_OPTION__VALUE);
+ checkValueTypeMatchesFieldType(option.getValue(), nodeForValueFeature, field);
+ }
+ }
+
+ private void checkValueTypeMatchesFieldType(Value value, INode nodeForValueFeature, MessageField field) {
+ if (messageFields.isString(field)) {
+ if (!(value instanceof StringLink)) {
+ error(expectedString, FIELD_OPTION__VALUE);
+ }
+ return;
+ }
+ if (messageFields.isBool(field)) {
+ if (!(value instanceof BooleanLink)) {
+ error(expectedTrueOrFalse, FIELD_OPTION__VALUE);
+ }
+ return;
+ }
+ Enum anEnum = modelFinder.enumTypeOf(field);
+ if (anEnum != null) {
+ if (!(value instanceof LiteralLink)) {
+ error(expectedIdentifier, FIELD_OPTION__VALUE);
+ }
+ Literal literal = ((LiteralLink) value).getTarget();
+ if (!anEnum.equals(literal.eContainer())) {
+ QualifiedName enumFqn = fqnProvider.getFullyQualifiedName(anEnum);
+ String literalName = nodes.textOf(nodeForValueFeature);
+ String msg = String.format(literalNotInEnum, enumFqn, literalName);
+ error(msg, FIELD_OPTION__VALUE);
+ }
+ return;
+ }
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java
index 92f36f1..cef1009 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java
@@ -17,6 +17,7 @@
public static String expectedFieldName;
public static String expectedFieldNumber;
+ public static String expectedIdentifier;
public static String expectedString;
public static String expectedSyntaxIdentifier;
public static String expectedTrueOrFalse;
@@ -24,6 +25,7 @@
public static String fieldNumbersMustBePositive;
public static String importingNonProto2;
public static String importNotFound;
+ public static String literalNotInEnum;
public static String missingFieldNumber;
public static String multiplePackages;
public static String nonProto2;
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
index adfad66..497a7cd 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
@@ -1,5 +1,6 @@
expectedFieldName = Expected field name.
expectedFieldNumber = Expected field number.
+expectedIdentifier = Expected identifier.
expectedString = Expected string.
expectedSyntaxIdentifier = Expected syntax identifier.
expectedTrueOrFalse = Expected "true" or "false".
@@ -7,6 +8,7 @@
fieldNumbersMustBePositive = Field numbers must be positive integers.
importingNonProto2 = Importing non-proto2 file (directly or indirectly.) This may cause errors related to unresolved references.
importNotFound = Import \"%s\" was not found.
+literalNotInEnum = Enum type \"%s\" has no value named \"%s\".
missingFieldNumber = Missing field number.
multiplePackages = Multiple package definitions.
nonProto2 = Deprecated syntax. This parser only recognizes \"proto2\".
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 4009bed..911bbb4 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
@@ -27,16 +27,14 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-@ComposedChecks(validators = { ImportValidator.class })
+@ComposedChecks(validators = { DataTypeValidator.class, ImportValidator.class })
public class ProtobufJavaValidator extends AbstractProtobufJavaValidator {
public static final String SYNTAX_IS_NOT_PROTO2_ERROR = "syntaxIsNotProto2";
public static final String INVALID_FIELD_TAG_NUMBER_ERROR = "invalidFieldTagNumber";
public static final String MORE_THAN_ONE_PACKAGE_ERROR = "moreThanOnePackage";
- @Inject private FieldOptions fieldOptions;
@Inject private IndexedElements indexedElements;
- @Inject private Fields properties;
@Inject private Protobufs protobufs;
@Inject private IQualifiedNameProvider qualifiedNameProvider;
@Inject private ImportUriResolver uriResolver;
@@ -47,20 +45,6 @@
}
}
- @Check public void checkDefaultValueType(FieldOption option) {
- if (!fieldOptions.isDefaultValueOption(option)) return;
- MessageField field = (MessageField) option.eContainer();
- Value defaultValue = option.getValue();
- if (properties.isString(field)) {
- if (defaultValue instanceof StringLink) return;
- error(expectedString, FIELD_OPTION__VALUE);
- }
- if (properties.isBool(field)) {
- if (defaultValue instanceof BooleanLink) return;
- error(expectedTrueOrFalse, FIELD_OPTION__VALUE);
- }
- }
-
@Check public void checkImportIsResolved(Import anImport) {
if (retryUntilItIsResolved(anImport)) return;
error(format(importNotFound, anImport.getImportURI()), IMPORT__IMPORT_URI);