X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fimpl%2FParserListenerUtils.java;h=83b56314cb93de7f7fbfd603e66d05b3966b5037;hb=feb866798e33453d6e9255e5f197a64296d33e93;hp=3ba54e404f44680010e47722baf848e4b993f590;hpb=df568194d106efa63c3138f0cc699dd53735cf44;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java index 3ba54e404f..83b56314cb 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java @@ -118,15 +118,17 @@ import org.opendaylight.yangtools.yang.model.util.Uint16; import org.opendaylight.yangtools.yang.model.util.Uint32; import org.opendaylight.yangtools.yang.model.util.Uint64; import org.opendaylight.yangtools.yang.model.util.Uint8; -import org.opendaylight.yangtools.yang.model.util.UnknownType; import org.opendaylight.yangtools.yang.parser.builder.api.Builder; import org.opendaylight.yangtools.yang.parser.builder.api.ConstraintsBuilder; import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.api.RefineBuilder; import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder; import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.RefineHolderImpl; +import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl; import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder; import org.opendaylight.yangtools.yang.parser.util.TypeConstraints; import org.opendaylight.yangtools.yang.parser.util.UnknownBoundaryNumber; @@ -139,7 +141,8 @@ public final class ParserListenerUtils { private static final Splitter KEYDEF_SPLITTER = Splitter.on(' ').omitEmptyStrings(); private static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults(); private static final Splitter DOT_DOT_SPLITTER = Splitter.on("..").trimResults(); - private static final CharMatcher QUOTE_MATCHER = CharMatcher.is('"'); + private static final CharMatcher DOUBLE_QUOTE_MATCHER = CharMatcher.is('"'); + private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher.is('\''); private ParserListenerUtils() { } @@ -166,33 +169,26 @@ public final class ParserListenerUtils { StringBuilder sb = new StringBuilder(); for (TerminalNode stringNode : context.STRING()) { final String str = stringNode.getText(); - final int i = str.indexOf('"'); - - if (i == -1) { + char firstChar = str.charAt(0); + final CharMatcher quoteMatcher; + if(SINGLE_QUOTE_MATCHER.matches(firstChar)) { + quoteMatcher = SINGLE_QUOTE_MATCHER; + } else if (DOUBLE_QUOTE_MATCHER.matches(firstChar)) { + quoteMatcher = DOUBLE_QUOTE_MATCHER; + } else { sb.append(str); continue; } - /* - * The string contains quotes, so we have to tread carefully. * - * FIXME: I think this code is broken, but proving that requires - * making sense of the parser/lexer and how they tie into - * this method. Especially what format 'str' can have and - * how we need to handle it. The original check was: + * It is safe not to check last argument to be same + * grammars enforces that. * - * if (!(result.startsWith("\"")) && result.endsWith("\"")) + * FIXME: Introduce proper escaping and translation of escaped + * characters here. * - * Looking at the parentheses it is hard to justify the - * pair right after negation -- the intent may have been - * to negate the entire expression. */ - if (i != 0 && str.endsWith("\"")) { - LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(context), - context.getStart().getLine()); - } else { - sb.append(QUOTE_MATCHER.removeFrom(str)); - } + sb.append(quoteMatcher.removeFrom(str.substring(1, str.length()-1))); } return sb.toString(); } @@ -379,7 +375,15 @@ public final class ParserListenerUtils { ParseTree child = ctx.getChild(i); if (child instanceof Value_stmtContext) { String valueStr = stringFromNode(child); - value = Integer.valueOf(valueStr); + try { + // yang enum value has same restrictions as JAVA Integer + value = Integer.valueOf(valueStr); + } catch (NumberFormatException e) { + String err = String + .format("Error on enum '%s': the enum value MUST be in the range from -2147483648 to 2147483647, but was: %s", + name, valueStr); + throw new YangParseException(moduleName, ctx.getStart().getLine(), err, e); + } } else if (child instanceof Description_stmtContext) { description = stringFromNode(child); } else if (child instanceof Reference_stmtContext) { @@ -392,10 +396,6 @@ public final class ParserListenerUtils { if (value == null) { value = highestValue + 1; } - if (value < -2147483648 || value > 2147483647) { - throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on enum '" + name - + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " + value); - } EnumPairImpl result = new EnumPairImpl(); result.qname = path.getPathTowardsRoot().iterator().next(); @@ -1036,62 +1036,51 @@ public final class ParserListenerUtils { } /** - * Parse type body and create UnknownType definition. + * Parse unknown type with body. * - * @param typedefQName - * qname of current type - * @param ctx + * @param typeBody * type body - * @param actualPath - * actual path in model - * @param namespace - * module namespace - * @param revision - * module revision - * @param prefix - * module prefix * @param parent * current node parent - * @return UnknownType object with constraints from parsed type body + * @param prefixedQName + * type qname with prefix + * @param moduleBuilder + * current module builder + * @param moduleQName + * current module qname + * @param actualPath + * actual path in model */ - public static TypeDefinition parseUnknownTypeWithBody(final QName typedefQName, - final Type_body_stmtsContext ctx, final SchemaPath actualPath, final QName moduleQName, final Builder parent) { - String moduleName = parent.getModuleName(); - String typeName = typedefQName.getLocalName(); - - UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName); - - if (ctx != null) { - List rangeStatements = getRangeConstraints(ctx, moduleName); - List lengthStatements = getLengthConstraints(ctx, moduleName); - List patternStatements = getPatternConstraint(ctx); - Integer fractionDigits = getFractionDigits(ctx, moduleName); - - if (parent instanceof TypeDefinitionBuilder) { - TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; - if (!(typedef instanceof UnionTypeBuilder)) { - typedef.setRanges(rangeStatements); - typedef.setLengths(lengthStatements); - typedef.setPatterns(patternStatements); - typedef.setFractionDigits(fractionDigits); - } - return unknownType.build(); - } else { - TypeDefinition baseType = unknownType.build(); - QName qname = QName.create(moduleQName, typeName); - SchemaPath schemaPath = createTypePath(actualPath, typeName); + public static void parseUnknownTypeWithBody(Type_body_stmtsContext typeBody, TypeAwareBuilder parent, + QName prefixedQName, ModuleBuilder moduleBuilder, QName moduleQName, SchemaPath actualPath) { + final int line = typeBody.getStart().getLine(); - ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, Optional.absent(), Optional.absent(), schemaPath); - typeBuilder.ranges(rangeStatements); - typeBuilder.lengths(lengthStatements); - typeBuilder.patterns(patternStatements); - typeBuilder.fractionDigits(fractionDigits); + List rangeStatements = getRangeConstraints(typeBody, moduleBuilder.getName()); + List lengthStatements = getLengthConstraints(typeBody, moduleBuilder.getName()); + List patternStatements = getPatternConstraint(typeBody); + Integer fractionDigits = getFractionDigits(typeBody, moduleBuilder.getName()); - return typeBuilder.build(); - } + if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) { + TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; + typedef.setRanges(rangeStatements); + typedef.setLengths(lengthStatements); + typedef.setPatterns(patternStatements); + typedef.setFractionDigits(fractionDigits); + typedef.setTypeQName(prefixedQName); + // add parent node of this type statement to dirty nodes + moduleBuilder.markActualNodeDirty(); + } else { + QName qname = QName.create(moduleQName, prefixedQName.getLocalName()); + SchemaPath schemaPath = createTypePath(actualPath, prefixedQName.getLocalName()); + TypeDefinitionBuilder typeBuilder = new TypeDefinitionBuilderImpl(moduleBuilder.getName(), line, qname, schemaPath); + typeBuilder.setRanges(rangeStatements); + typeBuilder.setLengths(lengthStatements); + typeBuilder.setPatterns(patternStatements); + typeBuilder.setFractionDigits(fractionDigits); + typeBuilder.setTypeQName(prefixedQName); + parent.setTypedef(typeBuilder); + moduleBuilder.getDirtyNodes().add(typeBuilder); } - - return unknownType.build(); } /** @@ -1103,12 +1092,8 @@ public final class ParserListenerUtils { * type body context * @param actualPath * current path in schema - * @param namespace - * current namespace - * @param revision - * current revision - * @param prefix - * current prefix + * @param moduleQName + * current module qname * @param parent * parent builder * @return TypeDefinition object based on parsed values.