X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fcode-generator%2Fyang-model-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fyang%2Fparser%2Futil%2FYangModelBuilderUtil.java;h=1e55b2444919fd67f5f46dd2114e8610e3d9e07f;hb=refs%2Fchanges%2F56%2F456%2F2;hp=0df5d2cbdfc1eaf99be41250b2f220995b8251de;hpb=626c9943156ed658f0a4cf11858ccc19b9c316cf;p=controller.git diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java index 0df5d2cbdf..1e55b24449 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java @@ -36,7 +36,9 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.Length_stmtContex import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_argContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Max_elements_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Max_value_argContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Min_elements_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Min_value_argContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Must_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Numerical_restrictionsContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_argContext; @@ -74,18 +76,24 @@ import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.Status; import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; +import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; +import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition; import org.opendaylight.controller.yang.model.api.type.LengthConstraint; import org.opendaylight.controller.yang.model.api.type.PatternConstraint; import org.opendaylight.controller.yang.model.api.type.RangeConstraint; +import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefinition; import org.opendaylight.controller.yang.model.util.BaseConstraints; +import org.opendaylight.controller.yang.model.util.BaseTypes; import org.opendaylight.controller.yang.model.util.BinaryType; import org.opendaylight.controller.yang.model.util.BitsType; import org.opendaylight.controller.yang.model.util.Decimal64; import org.opendaylight.controller.yang.model.util.EnumerationType; +import org.opendaylight.controller.yang.model.util.ExtendedType; import org.opendaylight.controller.yang.model.util.InstanceIdentifier; import org.opendaylight.controller.yang.model.util.Int16; import org.opendaylight.controller.yang.model.util.Int32; @@ -99,8 +107,12 @@ import org.opendaylight.controller.yang.model.util.Uint32; import org.opendaylight.controller.yang.model.util.Uint64; import org.opendaylight.controller.yang.model.util.Uint8; import org.opendaylight.controller.yang.model.util.UnknownType; +import org.opendaylight.controller.yang.parser.builder.api.Builder; import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -372,6 +384,7 @@ public final class YangModelBuilderUtil { } if (value < -2147483648 || value > 2147483647) { throw new YangParseException( + ctx.getStart().getLine(), "Error on enum '" + name + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " @@ -671,8 +684,8 @@ public final class YangModelBuilderUtil { try { result = Long.valueOf(value); } catch (NumberFormatException e) { - throw new YangParseException("Error on line " + line - + ": Unable to parse range value '" + value + "'.", e); + throw new YangParseException(line, + "Unable to parse range value '" + value + "'.", e); } } return result; @@ -790,7 +803,7 @@ public final class YangModelBuilderUtil { try { result = Integer.valueOf(value); } catch (NumberFormatException e) { - throw new YangParseException( + throw new YangParseException(ctx.getStart().getLine(), "Unable to parse fraction digits value '" + value + "'.", e); } @@ -888,6 +901,7 @@ public final class YangModelBuilderUtil { } if (position < 0 || position > 4294967295L) { throw new YangParseException( + ctx.getStart().getLine(), "Error on bit '" + name + "': the position value MUST be in the range 0 to 4294967295"); @@ -958,19 +972,48 @@ public final class YangModelBuilderUtil { * @return UnknownType object with constraints from parsed type body */ public static TypeDefinition parseUnknownTypeBody(QName typedefQName, - Type_body_stmtsContext ctx) { + Type_body_stmtsContext ctx, final List actualPath, + final URI namespace, final Date revision, final String prefix, + Builder parent, ModuleBuilder moduleBuilder) { + String typeName = typedefQName.getLocalName(); + UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName); + if (ctx != null) { List rangeStatements = getRangeConstraints(ctx); List lengthStatements = getLengthConstraints(ctx); List patternStatements = getPatternConstraint(ctx); Integer fractionDigits = getFractionDigits(ctx); - unknownType.rangeStatements(rangeStatements); - unknownType.lengthStatements(lengthStatements); - unknownType.patterns(patternStatements); - unknownType.fractionDigits(fractionDigits); + if (parent instanceof TypeDefinitionBuilder) { + TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; + typedef.setRanges(rangeStatements); + typedef.setLengths(lengthStatements); + typedef.setPatterns(patternStatements); + typedef.setFractionDigits(fractionDigits); + return unknownType.build(); + } else { + TypeDefinition baseType = unknownType.build(); + TypeDefinition result = null; + QName qname = new QName(namespace, revision, prefix, typeName); + ExtendedType.Builder typeBuilder = null; + + SchemaPath schemaPath = createTypeSchemaPath(actualPath, + namespace, revision, prefix, typeName, false, false); + typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", + schemaPath); + + typeBuilder.ranges(rangeStatements); + typeBuilder.lengths(lengthStatements); + typeBuilder.patterns(patternStatements); + typeBuilder.fractionDigits(fractionDigits); + + result = typeBuilder.build(); + + return result; + } } + return unknownType.build(); } @@ -994,8 +1037,8 @@ public final class YangModelBuilderUtil { public static TypeDefinition parseTypeBody(final String typeName, final Type_body_stmtsContext typeBody, final List actualPath, final URI namespace, - final Date revision, final String prefix) { - TypeDefinition type = null; + final Date revision, final String prefix, Builder parent) { + TypeDefinition baseType = null; List rangeStatements = getRangeConstraints(typeBody); Integer fractionDigits = getFractionDigits(typeBody); @@ -1004,62 +1047,143 @@ public final class YangModelBuilderUtil { List enumConstants = getEnumConstants( typeBody, actualPath, namespace, revision, prefix); + TypeConstraints constraints = new TypeConstraints(); + constraints.addFractionDigits(fractionDigits); + constraints.addLengths(lengthStatements); + constraints.addPatterns(patternStatements); + constraints.addRanges(rangeStatements); + + SchemaPath baseTypePathFinal = createTypeSchemaPath(actualPath, + namespace, revision, prefix, typeName, true, true); + SchemaPath baseTypePath = createTypeSchemaPath(actualPath, namespace, + revision, prefix, typeName, true, false); + if ("decimal64".equals(typeName)) { - type = new Decimal64(actualPath, namespace, revision, - fractionDigits); + if (rangeStatements.isEmpty()) { + return new Decimal64(baseTypePathFinal, fractionDigits); + } + Decimal64 decimalType = new Decimal64(baseTypePath, fractionDigits); + constraints.addRanges(decimalType.getRangeStatements()); + baseType = decimalType; } else if (typeName.startsWith("int")) { + IntegerTypeDefinition intType = null; if ("int8".equals(typeName)) { - type = new Int8(actualPath, namespace, revision, - rangeStatements, null, null); + intType = new Int8(baseTypePath); } else if ("int16".equals(typeName)) { - type = new Int16(actualPath, namespace, revision, - rangeStatements, null, null); + intType = new Int16(baseTypePath); } else if ("int32".equals(typeName)) { - type = new Int32(actualPath, namespace, revision, - rangeStatements, null, null); + intType = new Int32(baseTypePath); } else if ("int64".equals(typeName)) { - type = new Int64(actualPath, namespace, revision, - rangeStatements, null, null); + intType = new Int64(baseTypePath); } + constraints.addRanges(intType.getRangeStatements()); + baseType = intType; } else if (typeName.startsWith("uint")) { + UnsignedIntegerTypeDefinition uintType = null; if ("uint8".equals(typeName)) { - type = new Uint8(actualPath, namespace, revision, - rangeStatements, null, null); + uintType = new Uint8(baseTypePath); } else if ("uint16".equals(typeName)) { - type = new Uint16(actualPath, namespace, revision, - rangeStatements, null, null); + uintType = new Uint16(baseTypePath); } else if ("uint32".equals(typeName)) { - type = new Uint32(actualPath, namespace, revision, - rangeStatements, null, null); + uintType = new Uint32(baseTypePath); } else if ("uint64".equals(typeName)) { - type = new Uint64(actualPath, namespace, revision, - rangeStatements, null, null); + uintType = new Uint64(baseTypePath); } + constraints.addRanges(uintType.getRangeStatements()); + baseType = uintType; } else if ("enumeration".equals(typeName)) { - type = new EnumerationType(actualPath, namespace, revision, - enumConstants); + return new EnumerationType(baseTypePathFinal, enumConstants); } else if ("string".equals(typeName)) { - type = new StringType(actualPath, namespace, revision, - lengthStatements, patternStatements); + StringTypeDefinition stringType = new StringType(baseTypePath); + constraints.addLengths(stringType.getLengthStatements()); + baseType = stringType; } else if ("bits".equals(typeName)) { - type = new BitsType(actualPath, namespace, revision, getBits( - typeBody, actualPath, namespace, revision, prefix)); + return new BitsType(baseTypePathFinal, getBits(typeBody, + actualPath, namespace, revision, prefix)); } else if ("leafref".equals(typeName)) { final String path = parseLeafrefPath(typeBody); final boolean absolute = path.startsWith("/"); RevisionAwareXPath xpath = new RevisionAwareXPathImpl(path, absolute); - type = new Leafref(actualPath, namespace, revision, xpath); + return new Leafref(baseTypePathFinal, xpath); } else if ("binary".equals(typeName)) { - List bytes = Collections.emptyList(); - type = new BinaryType(actualPath, namespace, revision, bytes, - lengthStatements, null); + BinaryTypeDefinition binaryType = new BinaryType(baseTypePath); + constraints.addLengths(binaryType.getLengthConstraints()); + baseType = binaryType; } else if ("instance-identifier".equals(typeName)) { boolean requireInstance = isRequireInstance(typeBody); - type = new InstanceIdentifier(actualPath, namespace, revision, - null, requireInstance); + baseType = new InstanceIdentifier(baseTypePath, null, + requireInstance); } - return type; + + if (parent instanceof TypeDefinitionBuilder + && !(parent instanceof UnionTypeBuilder)) { + TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; + typedef.setRanges(constraints.getRange()); + typedef.setLengths(constraints.getLength()); + typedef.setPatterns(constraints.getPatterns()); + typedef.setFractionDigits(constraints.getFractionDigits()); + return baseType; + } + + TypeDefinition result = null; + QName qname = new QName(namespace, revision, prefix, typeName); + ExtendedType.Builder typeBuilder = null; + + SchemaPath schemaPath = createTypeSchemaPath(actualPath, namespace, + revision, prefix, typeName, false, false); + typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", + schemaPath); + + typeBuilder.ranges(constraints.getRange()); + typeBuilder.lengths(constraints.getLength()); + typeBuilder.patterns(constraints.getPatterns()); + typeBuilder.fractionDigits(constraints.getFractionDigits()); + + result = typeBuilder.build(); + return result; + } + + /** + * Create SchemaPath object from given path list with namespace, revision + * and prefix based on given values. + * + * @param actualPath + * current position in model + * @param namespace + * @param revision + * @param prefix + * @param typeName + * @param isBaseYangType + * if this is base yang type + * @param isBaseYangTypeFinal + * if this is base yang type without restrictions + * @return SchemaPath object. + */ + private static SchemaPath createTypeSchemaPath( + final List actualPath, final URI namespace, + final Date revision, final String prefix, final String typeName, + final boolean isBaseYangType, final boolean isBaseYangTypeFinal) { + List typePath = new ArrayList(actualPath); + if (isBaseYangType && !isBaseYangTypeFinal) { + typePath.add(typeName); + } + + final List path = new ArrayList(); + QName qname; + // start from index 1 -> module name omited + for (int i = 1; i < typePath.size(); i++) { + qname = new QName(namespace, revision, prefix, typePath.get(i)); + path.add(qname); + } + QName typeQName; + if (isBaseYangType) { + typeQName = new QName(BaseTypes.BaseTypesNamespace, typeName); + } else { + typeQName = new QName(namespace, revision, prefix, typeName); + } + path.add(typeQName); + return new SchemaPath(path, true); } /** @@ -1193,10 +1317,10 @@ public final class YangModelBuilderUtil { for (int i = 0; i < ctx.getChildCount(); ++i) { final ParseTree childNode = ctx.getChild(i); if (childNode instanceof Max_elements_stmtContext) { - Integer max = Integer.valueOf(stringFromNode(childNode)); - constraints.setMinElements(max); + Integer max = parseMaxElements((Max_elements_stmtContext) childNode); + constraints.setMaxElements(max); } else if (childNode instanceof Min_elements_stmtContext) { - Integer min = Integer.valueOf(stringFromNode(childNode)); + Integer min = parseMinElements((Min_elements_stmtContext) childNode); constraints.setMinElements(min); } else if (childNode instanceof Must_stmtContext) { MustDefinition must = parseMust((Must_stmtContext) childNode); @@ -1216,6 +1340,44 @@ public final class YangModelBuilderUtil { } } + private static Integer parseMinElements(Min_elements_stmtContext ctx) { + Integer result = null; + try { + for (int j = 0; j < ctx.getChildCount(); j++) { + ParseTree minArg = ctx.getChild(j); + if (minArg instanceof Min_value_argContext) { + result = Integer.valueOf(stringFromNode(minArg)); + } + } + if (result == null) { + throw new IllegalArgumentException(); + } + return result; + } catch (Exception e) { + throw new YangParseException(ctx.getStart().getLine(), + "Failed to parse min-elements.", e); + } + } + + private static Integer parseMaxElements(Max_elements_stmtContext ctx) { + Integer result = null; + try { + for (int j = 0; j < ctx.getChildCount(); j++) { + ParseTree maxArg = ctx.getChild(j); + if (maxArg instanceof Max_value_argContext) { + result = Integer.valueOf(stringFromNode(maxArg)); + } + } + if (result == null) { + throw new IllegalArgumentException(); + } + return result; + } catch (Exception e) { + throw new YangParseException(ctx.getStart().getLine(), + "Failed to parse max-elements.", e); + } + } + /** * Parse given context and return yin value. * @@ -1278,8 +1440,12 @@ public final class YangModelBuilderUtil { /** * Parse refine statement. - * @param refineCtx refine statement - * @return + * + * @param refineCtx + * refine statement + * @param line + * current line in yang model + * @return RefineHolder object representing this refine statement */ public static RefineHolder parseRefine(Refine_stmtContext refineCtx) { final String refineTarget = stringFromNode(refineCtx); @@ -1290,6 +1456,8 @@ public final class YangModelBuilderUtil { if (refinePom instanceof Refine_pomContext) { for (int k = 0; k < refinePom.getChildCount(); k++) { ParseTree refineStmt = refinePom.getChild(k); + parseRefineDefault(refine, refineStmt); + if (refineStmt instanceof Refine_leaf_stmtsContext) { parseRefine(refine, (Refine_leaf_stmtsContext) refineStmt); @@ -1315,6 +1483,23 @@ public final class YangModelBuilderUtil { return refine; } + private static void parseRefineDefault(RefineHolder refine, + ParseTree refineStmt) { + for (int i = 0; i < refineStmt.getChildCount(); i++) { + ParseTree refineArg = refineStmt.getChild(i); + if (refineArg instanceof Description_stmtContext) { + String description = stringFromNode(refineArg); + refine.setDescription(description); + } else if (refineArg instanceof Reference_stmtContext) { + String reference = stringFromNode(refineArg); + refine.setReference(reference); + } else if (refineArg instanceof Config_stmtContext) { + boolean config = parseConfig((Config_stmtContext) refineArg); + refine.setConfig(config); + } + } + } + private static RefineHolder parseRefine(RefineHolder refine, Refine_leaf_stmtsContext refineStmt) { for (int i = 0; i < refineStmt.getChildCount(); i++) { @@ -1362,10 +1547,10 @@ public final class YangModelBuilderUtil { MustDefinition must = parseMust((Must_stmtContext) refineArg); refine.setMust(must); } else if (refineArg instanceof Max_elements_stmtContext) { - Integer max = Integer.valueOf(stringFromNode(refineArg)); - refine.setMinElements(max); + Integer max = parseMaxElements((Max_elements_stmtContext) refineArg); + refine.setMaxElements(max); } else if (refineArg instanceof Min_elements_stmtContext) { - Integer min = Integer.valueOf(stringFromNode(refineArg)); + Integer min = parseMinElements((Min_elements_stmtContext) refineArg); refine.setMinElements(min); } } @@ -1380,10 +1565,10 @@ public final class YangModelBuilderUtil { MustDefinition must = parseMust((Must_stmtContext) refineArg); refine.setMust(must); } else if (refineArg instanceof Max_elements_stmtContext) { - Integer max = Integer.valueOf(stringFromNode(refineArg)); - refine.setMinElements(max); + Integer max = parseMaxElements((Max_elements_stmtContext) refineArg); + refine.setMaxElements(max); } else if (refineArg instanceof Min_elements_stmtContext) { - Integer min = Integer.valueOf(stringFromNode(refineArg)); + Integer min = parseMinElements((Min_elements_stmtContext) refineArg); refine.setMinElements(min); } }