Fixed: [ Issue 48 ] Validate duplicated tag numbers in a message
https://code.google.com/p/protobuf-dt/issues/detail?id=48
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 c82b6eb..d5a7c5f 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
@@ -15,17 +15,17 @@
*/
public class Messages extends NLS {
+ public static String expectedFieldName;
+ public static String expectedFieldNumber;
+ public static String expectedSyntaxIdentifier;
+ public static String fieldNumberAlreadyUsed;
+ public static String fieldNumbersMustBePositive;
+ public static String missingFieldNumber;
+ public static String unrecognizedSyntaxIdentifier;
+
static {
Class<Messages> targetType = Messages.class;
NLS.initializeMessages(targetType.getName(), targetType);
}
-
private Messages() {}
-
- public static String Error_expectedFieldName;
- public static String Error_expectedFieldNumber;
- public static String Error_missingFieldNumber;
- public static String Error_fieldNumbersMustBePositive;
- public static String Error_unrecognizedSyntaxIdentifier;
- public static String Error_expectedSyntaxIdentifier;
}
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 dcb7afe..a2d416e 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,6 +1,7 @@
-Error_expectedFieldName = Expected field name.
-Error_expectedFieldNumber = Expected field number.
-Error_missingFieldNumber = Missing field number.
-Error_fieldNumbersMustBePositive = Field numbers must be positive integers.
-Error_unrecognizedSyntaxIdentifier = Unrecognized syntax identifier \"%s\". This parser only recognizes \"proto2\".
-Error_expectedSyntaxIdentifier = Expected syntax identifier.
+expectedFieldName = Expected field name.
+expectedFieldNumber = Expected field number.
+missingFieldNumber = Missing field number.
+fieldNumberAlreadyUsed = Field number %d has already been used in \"%s\" by field \"%s\".
+fieldNumbersMustBePositive = Field numbers must be positive integers.
+unrecognizedSyntaxIdentifier = Unrecognized syntax identifier \"%s\". This parser only recognizes \"proto2\".
+expectedSyntaxIdentifier = Expected syntax identifier.
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 84bd3ba..04b514f 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
@@ -8,34 +8,63 @@
*/
package com.google.eclipse.protobuf.validation;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.*;
import static com.google.eclipse.protobuf.validation.Messages.*;
import static java.lang.String.format;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.*;
import org.eclipse.xtext.validation.Check;
import com.google.eclipse.protobuf.protobuf.*;
+import com.google.inject.Inject;
/**
* @author alruiz@google.com (Alex Ruiz)
*/
public class ProtobufJavaValidator extends AbstractProtobufJavaValidator {
+ @Inject private IQualifiedNameProvider qualifiedNameProvider;
+
+ @Check public void checkTagNumberIsDuplicated(Property property) {
+ if (isNameNull(property)) return; // we already show an error if name is null, no need to go further.
+ int index = property.getIndex();
+ EObject container = property.eContainer();
+ if (container instanceof Message) {
+ Message message = (Message) container;
+ for (MessageElement element : message.getElements()) {
+ if (!(element instanceof Property)) continue;
+ Property p = (Property) element;
+ if (p == property) break;
+ if (p.getIndex() != index) continue;
+ QualifiedName messageName = qualifiedNameProvider.getFullyQualifiedName(message);
+ String msg = format(fieldNumberAlreadyUsed, index, messageName.toString(), p.getName());
+ error(msg, PROPERTY__INDEX);
+ break;
+ }
+ }
+ }
+
/**
* Creates an error if the tag number of the given property is less than zero.
* @param property the given property.
*/
@Check public void checkTagNumberIsGreaterThanZero(Property property) {
- if (property.getName() == null) return; // we already show an error if name is null, no need to go further.
+ if (isNameNull(property)) return; // we already show an error if name is null, no need to go further.
int index = property.getIndex();
if (index > 0) return;
- String msg = (index == 0) ? Error_fieldNumbersMustBePositive : Error_expectedFieldNumber;
- error(msg, property.eClass().getEStructuralFeature("index"));
+ String msg = (index == 0) ? fieldNumbersMustBePositive : expectedFieldNumber;
+ error(msg, PROPERTY__INDEX);
+ }
+
+ private boolean isNameNull(Property property) {
+ return property.getName() == null;
}
@Check public void checkSyntaxIsProto2(Syntax syntax) {
String name = syntax.getName();
if ("proto2".equals(name)) return;
- String msg = (name == null) ? Error_expectedSyntaxIdentifier : format(Error_unrecognizedSyntaxIdentifier, name);
- error(msg, syntax.eClass().getEStructuralFeature("name"));
+ String msg = (name == null) ? expectedSyntaxIdentifier : format(unrecognizedSyntaxIdentifier, name);
+ error(msg, SYNTAX__NAME);
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufSyntaxErrorMessageProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufSyntaxErrorMessageProvider.java
index f22837a..a67b593 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufSyntaxErrorMessageProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufSyntaxErrorMessageProvider.java
@@ -34,9 +34,9 @@
private String mapToProtocMessage(String message, Property property) {
if (message.contains("RULE_ID") && property.getName() == null)
- return Error_expectedFieldName;
+ return expectedFieldName;
if (message.equals("mismatched input ';' expecting '='") && property.getIndex() == 0)
- return Error_missingFieldNumber;
+ return missingFieldNumber;
return message;
}