Fixed: [ Issue 67 ] 'nan' is a valid default value for double and float https://code.google.com/p/protobuf-dt/issues/detail?id=67 Also added validations for default string and boolean values.
diff --git a/com.google.eclipse.protobuf/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf/META-INF/MANIFEST.MF index f4159fc..be7f077 100644 --- a/com.google.eclipse.protobuf/META-INF/MANIFEST.MF +++ b/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
@@ -21,6 +21,7 @@ org.apache.commons.logging Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: com.google.eclipse.protobuf, + com.google.eclipse.protobuf.grammar, com.google.eclipse.protobuf.parseTreeConstruction, com.google.eclipse.protobuf.parser.antlr, com.google.eclipse.protobuf.parser.antlr.internal,
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext index a14878e..0f0c32e 100644 --- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext +++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
@@ -108,7 +108,9 @@ | BooleanRef | IntRef | FloatRef - | StringRef; + | DoubleRef + | StringRef + | Nan; LiteralRef: literal=[Literal]; @@ -126,9 +128,15 @@ FloatRef: float=FLOAT; +DoubleRef: + double=DOUBLE; + StringRef: string=STRING; +Nan: + number='nan'; + Enum: 'enum' name=Name '{' literals+=Literal* @@ -163,4 +171,5 @@ terminal INT returns ecore::EInt: ('-')? ('0'..'9')+; terminal FLOAT returns ecore::EFloat: ('-')? ('0'..'9')* ('.' ('0'..'9')+)?; +terminal DOUBLE returns ecore::EDouble: ('-')? ('0'..'9')* ('.' ('0'..'9')+)?; \ No newline at end of file
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/grammar/CommonKeyword.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/grammar/CommonKeyword.java new file mode 100644 index 0000000..d00648c --- /dev/null +++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/grammar/CommonKeyword.java
@@ -0,0 +1,47 @@ +/* + * 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.grammar; + +/** + * A commonly used keyword. + * + * @author alruiz@google.com (Alex Ruiz) + */ +public enum CommonKeyword { + + // we used to get keywords from IGrammarAccess. The problem was that we still had to hardcode the keyword we were + // looking for. The code was too complicated and if the grammar changed for some reason, we had to change our + // implementation anyway. + + BOOL("bool"), TRUE("true"), FALSE("false"), BYTES("bytes"), OPENING_BRACKET("["), CLOSING_BRACKET("]"), + DEFAULT("default"), EQUAL("="), SEMICOLON(";"), STRING("string"), SYNTAX("syntax"); + + private final String value; + + private CommonKeyword(String value) { + this.value = value; + } + + /** + * Indicates whether the value of this keyword is equal to the given {@code String}. + * @param s the value to compare to. + * @return {@code true} if the value of this keyword is equal to the given {@code String}, {@code false} otherwise. + */ + public boolean hasValue(String s) { + return value.equals(s); + } + + /** + * Returns the textual value of this keyword. + * @return the textual value of this keyword. + */ + @Override public String toString() { + return value; + } +}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java new file mode 100644 index 0000000..3ddcd47 --- /dev/null +++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
@@ -0,0 +1,75 @@ +/* + * 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.util; + +import static com.google.eclipse.protobuf.grammar.CommonKeyword.*; + +import com.google.eclipse.protobuf.grammar.CommonKeyword; +import com.google.eclipse.protobuf.protobuf.*; +import com.google.inject.Singleton; + +/** + * Utility methods re <code>{@link Property}</code>. + * + * @author alruiz@google.com (Alex Ruiz) + */ +@Singleton +public class Properties { + + /** + * Indicates whether the type of the given property is primitive. Primitive types include: {@code double}, + * {@code float}, {@code int32}, {@code int64}, {@code uint32}, {@code uint64}, {@code sint32}, {@code sint64}, + * {@code fixed32}, {@code fixed64}, {@code sfixed32}, {@code sfixed64} and {@code bool}. + * @param p the given property. + * @return {@code true} if the type of the given property is primitive, {@code false} otherwise. + */ + public boolean isPrimitive(Property p) { + AbstractTypeReference r = p.getType(); + if (!(r instanceof ScalarTypeReference)) return false; + String typeName = ((ScalarTypeReference) r).getScalar().getName(); + return !STRING.hasValue(typeName) && !BYTES.hasValue(typeName); + } + + /** + * Indicates whether the given property is of type {@code bool}. + * @param p the given property. + * @return {@code true} if the given property is of type {@code bool}, {@code false} otherwise. + */ + public boolean isBool(Property p) { + return isScalarType(p, BOOL); + } + + /** + * Indicates whether the given property is of type {@code string}. + * @param p the given property. + * @return {@code true} if the given property is of type {@code string}, {@code false} otherwise. + */ + public boolean isString(Property p) { + return isScalarType(p, STRING); + } + + private boolean isScalarType(Property p, CommonKeyword typeKeyword) { + return typeKeyword.hasValue(typeNameOf(p)); + } + + /** + * Returns the name of the type of the given <code>{@link Property}</code>. + * @param p the given {@code Property}. + * @return the name of the type of the given {@code Property}. + */ + public String typeNameOf(Property p) { + AbstractTypeReference r = p.getType(); + if (r instanceof ScalarTypeReference) return ((ScalarTypeReference) r).getScalar().getName(); + if (r instanceof TypeReference) { + Type type = ((TypeReference) r).getType(); + return type == null ? null : type.getName(); + } + return r.toString(); + } +}
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 cbd6fa0..7bbe1d8 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,7 +17,9 @@ public static String expectedFieldName; public static String expectedFieldNumber; + public static String expectedString; public static String expectedSyntaxIdentifier; + public static String expectedTrueOrFalse; public static String fieldNumberAlreadyUsed; public static String fieldNumbersMustBePositive; public static String importNotFound;
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 dbb5a26..cc7c6ed 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,8 @@ expectedFieldName = Expected field name. expectedFieldNumber = Expected field number. +expectedString = Expected string. expectedSyntaxIdentifier = Expected syntax identifier. +expectedTrueOrFalse = Expected "true" or "false". fieldNumberAlreadyUsed = Field number %d has already been used in \"%s\" by field \"%s\". fieldNumbersMustBePositive = Field numbers must be positive integers. importNotFound = Import \"%s\" was not found.
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 22a6323..a818e82 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,6 +8,7 @@ */ package com.google.eclipse.protobuf.validation; +import static com.google.eclipse.protobuf.protobuf.Modifier.OPTIONAL; import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.*; import static com.google.eclipse.protobuf.validation.Messages.*; import static java.lang.String.format; @@ -15,11 +16,13 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; -import org.eclipse.xtext.naming.*; +import org.eclipse.xtext.naming.IQualifiedNameProvider; +import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.validation.Check; import com.google.eclipse.protobuf.protobuf.*; import com.google.eclipse.protobuf.protobuf.Package; +import com.google.eclipse.protobuf.util.Properties; import com.google.inject.Inject; /** @@ -28,6 +31,20 @@ public class ProtobufJavaValidator extends AbstractProtobufJavaValidator { @Inject private IQualifiedNameProvider qualifiedNameProvider; + @Inject private Properties properties; + + @Check public void checkDefaultValueType(Property property) { + ValueRef defaultValue = property.getDefault(); + if (!OPTIONAL.equals(property.getModifier()) || defaultValue == null) return; + if (properties.isString(property)) { + if (defaultValue instanceof StringRef) return; + error(expectedString, PROPERTY__DEFAULT); + } + if (properties.isBool(property)) { + if (defaultValue instanceof BooleanRef) return; + error(expectedTrueOrFalse, PROPERTY__DEFAULT); + } + } @Check public void checkImportIsResolved(Import anImport) { String importUri = anImport.getImportURI();