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%2Fmodel%2Fparser%2Fimpl%2FYangModelParserImpl.java;h=fce723edff9ea6ebd32b7d814ad371d00abaa53a;hb=refs%2Fchanges%2F03%2F103%2F3;hp=d7c6711affb740de272f754e76e331561782f8ba;hpb=f5bc1a15da8600a9bc6dc7829792566cf0e72e7c;p=controller.git diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserImpl.java index d7c6711aff..fce723edff 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserImpl.java @@ -9,7 +9,9 @@ package org.opendaylight.controller.yang.model.parser.impl; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -26,22 +28,6 @@ import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.opendaylight.controller.antlrv4.code.gen.YangLexer; import org.opendaylight.controller.antlrv4.code.gen.YangParser; -import org.opendaylight.controller.model.api.type.BinaryTypeDefinition; -import org.opendaylight.controller.model.api.type.BitsTypeDefinition; -import org.opendaylight.controller.model.api.type.BitsTypeDefinition.Bit; -import org.opendaylight.controller.model.api.type.DecimalTypeDefinition; -import org.opendaylight.controller.model.api.type.InstanceIdentifierTypeDefinition; -import org.opendaylight.controller.model.api.type.IntegerTypeDefinition; -import org.opendaylight.controller.model.api.type.LengthConstraint; -import org.opendaylight.controller.model.api.type.PatternConstraint; -import org.opendaylight.controller.model.api.type.RangeConstraint; -import org.opendaylight.controller.model.api.type.StringTypeDefinition; -import org.opendaylight.controller.model.util.BaseConstraints; -import org.opendaylight.controller.model.util.BinaryType; -import org.opendaylight.controller.model.util.BitsType; -import org.opendaylight.controller.model.util.StringType; -import org.opendaylight.controller.model.util.UnknownType; -import org.opendaylight.controller.model.util.YangTypesConverter; import org.opendaylight.controller.yang.common.QName; import org.opendaylight.controller.yang.model.api.AugmentationSchema; import org.opendaylight.controller.yang.model.api.DataSchemaNode; @@ -53,6 +39,16 @@ import org.opendaylight.controller.yang.model.api.RpcDefinition; import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.TypeDefinition; +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.DecimalTypeDefinition; +import org.opendaylight.controller.yang.model.api.type.InstanceIdentifierTypeDefinition; +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.BitsTypeDefinition.Bit; import org.opendaylight.controller.yang.model.parser.api.YangModelParser; import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder; import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationTargetBuilder; @@ -61,6 +57,13 @@ import org.opendaylight.controller.yang.model.parser.builder.api.DataSchemaNodeB import org.opendaylight.controller.yang.model.parser.builder.api.TypeAwareBuilder; import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder; import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder; +import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder; +import org.opendaylight.controller.yang.model.util.BaseConstraints; +import org.opendaylight.controller.yang.model.util.BinaryType; +import org.opendaylight.controller.yang.model.util.BitsType; +import org.opendaylight.controller.yang.model.util.StringType; +import org.opendaylight.controller.yang.model.util.UnknownType; +import org.opendaylight.controller.yang.model.util.YangTypesConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,14 +74,22 @@ public class YangModelParserImpl implements YangModelParser { @Override public Module parseYangModel(String yangFile) { - final Map> modules = loadFiles(yangFile); + final Map> modules = resolveModuleBuildersFromStreams(yangFile); Set result = build(modules); return result.iterator().next(); } @Override public Set parseYangModels(String... yangFiles) { - final Map> modules = loadFiles(yangFiles); + final Map> modules = resolveModuleBuildersFromStreams(yangFiles); + Set result = build(modules); + return result; + } + + @Override + public Set parseYangModelsFromStreams( + InputStream... yangModelStreams) { + final Map> modules = resolveModuleBuildersFromStreams(yangModelStreams); Set result = build(modules); return result; } @@ -88,14 +99,31 @@ public class YangModelParserImpl implements YangModelParser { return new SchemaContextImpl(modules); } - private Map> loadFiles( + private Map> resolveModuleBuildersFromStreams( String... yangFiles) { + InputStream[] streams = new InputStream[yangFiles.length]; + for(int i = 0; i < yangFiles.length; i++) { + final String yangFileName = yangFiles[i]; + final File yangFile = new File(yangFileName); + FileInputStream inStream = null; + try { + inStream = new FileInputStream(yangFile); + } catch(FileNotFoundException e) { + logger.warn("Exception while reading yang stream: " + inStream, e); + } + streams[i] = inStream; + } + return resolveModuleBuildersFromStreams(streams); + } + + private Map> resolveModuleBuildersFromStreams( + InputStream... yangFiles) { final Map> modules = new HashMap>(); final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl(); final ParseTreeWalker walker = new ParseTreeWalker(); - List trees = parseFiles(yangFiles); + List trees = parseStreams(yangFiles); ModuleBuilder[] builders = new ModuleBuilder[trees.size()]; @@ -123,26 +151,24 @@ public class YangModelParserImpl implements YangModelParser { return modules; } - private List parseFiles(String... yangFileNames) { + private List parseStreams(InputStream... yangStreams) { List trees = new ArrayList(); - for (String fileName : yangFileNames) { - trees.add(parseFile(fileName)); + for (InputStream yangStream : yangStreams) { + trees.add(parseStream(yangStream)); } return trees; } - private ParseTree parseFile(String yangFileName) { + private ParseTree parseStream(InputStream yangStream) { ParseTree result = null; try { - final File yangFile = new File(yangFileName); - final FileInputStream inStream = new FileInputStream(yangFile); - final ANTLRInputStream input = new ANTLRInputStream(inStream); + final ANTLRInputStream input = new ANTLRInputStream(yangStream); final YangLexer lexer = new YangLexer(input); final CommonTokenStream tokens = new CommonTokenStream(lexer); final YangParser parser = new YangParser(tokens); result = parser.yang(); } catch (IOException e) { - logger.warn("Exception while reading yang file: " + yangFileName, e); + logger.warn("Exception while reading yang file: " + yangStream, e); } return result; } @@ -187,13 +213,13 @@ public class YangModelParserImpl implements YangModelParser { * * @param modules * all available modules - * @param builder + * @param module * current module */ private void resolveTypedefs( Map> modules, - ModuleBuilder builder) { - Map, TypeAwareBuilder> dirtyNodes = builder + ModuleBuilder module) { + Map, TypeAwareBuilder> dirtyNodes = module .getDirtyNodes(); if (dirtyNodes.size() == 0) { return; @@ -201,131 +227,165 @@ public class YangModelParserImpl implements YangModelParser { for (Map.Entry, TypeAwareBuilder> entry : dirtyNodes .entrySet()) { TypeAwareBuilder typeToResolve = entry.getValue(); - Map foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints( - modules, entry.getValue(), builder); - TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder - .entrySet().iterator().next().getKey(); - TypeConstraints constraints = foundedTypeDefinitionBuilder - .entrySet().iterator().next().getValue(); - - UnknownType ut = (UnknownType) typeToResolve.getType(); - - // RANGE - List ranges = ut.getRangeStatements(); - resolveRanges(ranges, typeToResolve, targetType, modules, - builder); - // LENGTH - List lengths = ut.getLengthStatements(); - resolveLengths(lengths, typeToResolve, targetType, modules, - builder); - - // PATTERN - List patterns = ut.getPatterns(); - - // Fraction Digits - Integer fractionDigits = ut.getFractionDigits(); - - TypeDefinition type = targetType.getBaseType(); - String typeName = type.getQName().getLocalName(); - - // MERGE CONSTRAINTS (enumeration and leafref omitted because - // they have no restrictions) - if (type instanceof DecimalTypeDefinition) { - List fullRanges = new ArrayList(); - fullRanges.addAll(constraints.getRanges()); - fullRanges.addAll(ranges); - Integer fd = fractionDigits == null ? constraints - .getFractionDigits() : fractionDigits; - type = YangTypesConverter.javaTypeForBaseYangDecimal64Type( - fullRanges, fd); - } else if (type instanceof IntegerTypeDefinition) { - List fullRanges = new ArrayList(); - fullRanges.addAll(constraints.getRanges()); - fullRanges.addAll(ranges); - if (typeName.startsWith("int")) { - type = YangTypesConverter - .javaTypeForBaseYangSignedIntegerType(typeName, - fullRanges); - } else { - type = YangTypesConverter - .javaTypeForBaseYangUnsignedIntegerType( - typeName, fullRanges); - } - } else if (type instanceof StringTypeDefinition) { - List fullLengths = new ArrayList(); - fullLengths.addAll(constraints.getLengths()); - fullLengths.addAll(lengths); - List fullPatterns = new ArrayList(); - fullPatterns.addAll(constraints.getPatterns()); - fullPatterns.addAll(patterns); - type = new StringType(fullLengths, fullPatterns); - } else if (type instanceof BitsTypeDefinition) { - // TODO: add 'length' restriction to BitsType - BitsTypeDefinition bitsType = (BitsTypeDefinition) type; - List bits = bitsType.getBits(); - type = new BitsType(bits); - } else if (type instanceof BinaryTypeDefinition) { - type = new BinaryType(null, lengths, null); - } else if (typeName.equals("instance-identifier")) { - // TODO: instance-identifier - /* - * boolean requireInstance = isRequireInstance(typeBody); - * type = new InstanceIdentifier(null, requireInstance); - */ + if (typeToResolve instanceof UnionTypeBuilder) { + resolveUnionTypeBuilder(modules, module, + (UnionTypeBuilder) typeToResolve); + } else { + UnknownType ut = (UnknownType) typeToResolve.getType(); + TypeDefinition resolvedType = findTargetType(ut, + modules, module); + typeToResolve.setType(resolvedType); } - typeToResolve.setType(type); } } } + private UnionTypeBuilder resolveUnionTypeBuilder( + Map> modules, + ModuleBuilder builder, UnionTypeBuilder unionTypeBuilderToResolve) { + + List> resolvedTypes = new ArrayList>(); + List> typesToRemove = new ArrayList>(); + + for (TypeDefinition td : unionTypeBuilderToResolve.getTypes()) { + if (td instanceof UnknownType) { + TypeDefinition resolvedType = findTargetType( + (UnknownType) td, modules, builder); + resolvedTypes.add(resolvedType); + typesToRemove.add(td); + } + } + + List> unionTypeBuilderTypes = unionTypeBuilderToResolve + .getTypes(); + unionTypeBuilderTypes.addAll(resolvedTypes); + unionTypeBuilderTypes.removeAll(typesToRemove); + + return unionTypeBuilderToResolve; + } + + private TypeDefinition findTargetType(UnknownType ut, + Map> modules, + ModuleBuilder builder) { + + Map foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints( + modules, ut, builder); + TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder + .entrySet().iterator().next().getKey(); + TypeConstraints constraints = foundedTypeDefinitionBuilder.entrySet() + .iterator().next().getValue(); + + TypeDefinition targetTypeBaseType = targetType.getBaseType(); + String targetTypeBaseTypeName = targetTypeBaseType.getQName() + .getLocalName(); + + // RANGE + List ranges = ut.getRangeStatements(); + resolveRanges(ranges, targetType, modules, builder); + + // LENGTH + List lengths = ut.getLengthStatements(); + resolveLengths(lengths, targetType, modules, builder); + + // PATTERN + List patterns = ut.getPatterns(); + + // Fraction Digits + Integer fractionDigits = ut.getFractionDigits(); + + // MERGE CONSTRAINTS (enumeration and leafref omitted + // because + // they have no restrictions) + if (targetTypeBaseType instanceof DecimalTypeDefinition) { + List fullRanges = new ArrayList(); + fullRanges.addAll(constraints.getRanges()); + fullRanges.addAll(ranges); + Integer fd = fractionDigits == null ? constraints + .getFractionDigits() : fractionDigits; + targetTypeBaseType = YangTypesConverter + .javaTypeForBaseYangDecimal64Type(fullRanges, fd); + } else if (targetTypeBaseType instanceof IntegerTypeDefinition) { + List fullRanges = new ArrayList(); + fullRanges.addAll(constraints.getRanges()); + fullRanges.addAll(ranges); + if (targetTypeBaseTypeName.startsWith("int")) { + targetTypeBaseType = YangTypesConverter + .javaTypeForBaseYangSignedIntegerType( + targetTypeBaseTypeName, fullRanges); + } else { + targetTypeBaseType = YangTypesConverter + .javaTypeForBaseYangUnsignedIntegerType( + targetTypeBaseTypeName, fullRanges); + } + } else if (targetTypeBaseType instanceof StringTypeDefinition) { + List fullLengths = new ArrayList(); + fullLengths.addAll(constraints.getLengths()); + fullLengths.addAll(lengths); + List fullPatterns = new ArrayList(); + fullPatterns.addAll(constraints.getPatterns()); + fullPatterns.addAll(patterns); + targetTypeBaseType = new StringType(fullLengths, fullPatterns); + } else if (targetTypeBaseType instanceof BitsTypeDefinition) { + BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType; + List bits = bitsType.getBits(); + targetTypeBaseType = new BitsType(bits); + } else if (targetTypeBaseType instanceof BinaryTypeDefinition) { + targetTypeBaseType = new BinaryType(null, lengths, null); + } else if (targetTypeBaseTypeName.equals("instance-identifier")) { + // TODO: instance-identifier + /* + * boolean requireInstance = isRequireInstance(typeBody); type = new + * InstanceIdentifier(null, requireInstance); + */ + } + + return targetTypeBaseType; + } + private TypeDefinitionBuilder findTypeDefinitionBuilder( Map> modules, - TypeAwareBuilder typeBuilder, ModuleBuilder builder) { + UnknownType unknownType, ModuleBuilder builder) { Map result = findTypeDefinitionBuilderWithConstraints( - modules, typeBuilder, builder); + modules, unknownType, builder); return result.entrySet().iterator().next().getKey(); } private Map findTypeDefinitionBuilderWithConstraints( Map> modules, - TypeAwareBuilder typeBuilder, ModuleBuilder builder) { + UnknownType unknownType, ModuleBuilder builder) { return findTypeDefinitionBuilderWithConstraints(new TypeConstraints(), - modules, typeBuilder, builder); + modules, unknownType, builder); } /** * Traverse through all referenced types chain until base YANG type is * founded. * - * @param constraints - * current type constraints - * @param modules - * all available modules - * @param typeBuilder - * type builder which contains type - * @param builder - * current module + * @param constraints current type constraints + * @param modules all available modules + * @param unknownType unknown type + * @param builder current module * @return map, where key is type referenced and value is its constraints */ private Map findTypeDefinitionBuilderWithConstraints( TypeConstraints constraints, Map> modules, - TypeAwareBuilder typeBuilder, ModuleBuilder builder) { + UnknownType unknownType, ModuleBuilder builder) { Map result = new HashMap(); - UnknownType type = (UnknownType) typeBuilder.getType(); - QName typeQName = type.getQName(); - String typeName = type.getQName().getLocalName(); - String prefix = typeQName.getPrefix(); + // TypeDefinition unknownType = typeBuilder.getType(); + QName unknownTypeQName = unknownType.getQName(); + String unknownTypeName = unknownTypeQName.getLocalName(); + String unknownTypePrefix = unknownTypeQName.getPrefix(); // search for module which contains referenced typedef ModuleBuilder dependentModuleBuilder; - if (prefix.equals(builder.getPrefix())) { + if (unknownTypePrefix.equals(builder.getPrefix())) { dependentModuleBuilder = builder; } else { ModuleImport dependentModuleImport = getModuleImport(builder, - prefix); + unknownTypePrefix); String dependentModuleName = dependentModuleImport.getModuleName(); Date dependentModuleRevision = dependentModuleImport.getRevision(); TreeMap moduleBuildersByRevision = modules @@ -346,7 +406,7 @@ public class YangModelParserImpl implements YangModelParser { TypeDefinitionBuilder lookedUpBuilder = null; for (TypeDefinitionBuilder tdb : typedefs) { QName qname = tdb.getQName(); - if (qname.getLocalName().equals(typeName)) { + if (qname.getLocalName().equals(unknownTypeName)) { lookedUpBuilder = tdb; break; } @@ -366,8 +426,7 @@ public class YangModelParserImpl implements YangModelParser { final List patterns = unknown.getPatterns(); constraints.addPatterns(patterns); return findTypeDefinitionBuilderWithConstraints(constraints, - modules, (TypeAwareBuilder) lookedUpBuilder, - dependentModuleBuilder); + modules, unknown, dependentModuleBuilder); } else { // pull restriction from this base type and add them to // 'constraints' @@ -383,16 +442,14 @@ public class YangModelParserImpl implements YangModelParser { } else if (referencedType instanceof StringTypeDefinition) { constraints.addPatterns(((StringTypeDefinition) referencedType) .getPatterns()); - } else if (referencedType instanceof BitsTypeDefinition) { - // TODO: add 'length' restriction to BitsType } else if (referencedType instanceof BinaryTypeDefinition) { - // TODO + constraints.addLengths(((BinaryTypeDefinition) referencedType) + .getLengthConstraints()); } else if (referencedType instanceof InstanceIdentifierTypeDefinition) { // TODO: instance-identifier } result.put(lookedUpBuilder, constraints); - // return lookedUpBuilder; return result; } } @@ -403,13 +460,13 @@ public class YangModelParserImpl implements YangModelParser { * * @param modules * all available modules - * @param builder + * @param module * current module */ private void resolveAugments( Map> modules, - ModuleBuilder builder) { - Set augmentBuilders = builder + ModuleBuilder module) { + Set augmentBuilders = module .getAddedAugments(); Set augments = new HashSet(); @@ -421,7 +478,7 @@ public class YangModelParserImpl implements YangModelParser { prefix = pathPart.getPrefix(); augmentTargetPath.add(pathPart.getLocalName()); } - ModuleImport dependentModuleImport = getModuleImport(builder, + ModuleImport dependentModuleImport = getModuleImport(module, prefix); String dependentModuleName = dependentModuleImport.getModuleName(); augmentTargetPath.add(0, dependentModuleName); @@ -446,7 +503,7 @@ public class YangModelParserImpl implements YangModelParser { fillAugmentTarget(augmentBuilder, (ChildNodeBuilder) augmentTarget); augments.add(result); } - builder.setAugmentations(augments); + module.setAugmentations(augments); } /** @@ -487,19 +544,13 @@ public class YangModelParserImpl implements YangModelParser { * Helper method for resolving special 'min' or 'max' values in range * constraint * - * @param ranges - * ranges to resolve - * @param typeToResolve - * type to resolve - * @param targetType - * target type - * @param modules - * all available modules - * @param builder - * current module + * @param ranges ranges to resolve + * @param targetType target type + * @param modules all available modules + * @param builder current module */ private void resolveRanges(List ranges, - TypeAwareBuilder typeToResolve, TypeDefinitionBuilder targetType, + TypeDefinitionBuilder targetType, Map> modules, ModuleBuilder builder) { if (ranges != null && ranges.size() > 0) { @@ -507,8 +558,8 @@ public class YangModelParserImpl implements YangModelParser { Long max = (Long) ranges.get(ranges.size() - 1).getMax(); // if range contains one of the special values 'min' or 'max' if (min.equals(Long.MIN_VALUE) || max.equals(Long.MAX_VALUE)) { - Long[] values = parseRangeConstraint(typeToResolve, targetType, - modules, builder); + Long[] values = parseRangeConstraint(targetType, modules, + builder); if (min.equals(Long.MIN_VALUE)) { min = values[0]; RangeConstraint oldFirst = ranges.get(0); @@ -533,19 +584,13 @@ public class YangModelParserImpl implements YangModelParser { * Helper method for resolving special 'min' or 'max' values in length * constraint * - * @param ranges - * ranges to resolve - * @param typeToResolve - * type to resolve - * @param targetType - * target type - * @param modules - * all available modules - * @param builder - * current module + * @param lengths lengths to resolve + * @param targetType target type + * @param modules all available modules + * @param builder current module */ private void resolveLengths(List lengths, - TypeAwareBuilder typeToResolve, TypeDefinitionBuilder targetType, + TypeDefinitionBuilder targetType, Map> modules, ModuleBuilder builder) { if (lengths != null && lengths.size() > 0) { @@ -553,8 +598,8 @@ public class YangModelParserImpl implements YangModelParser { Long max = lengths.get(lengths.size() - 1).getMax(); // if length contains one of the special values 'min' or 'max' if (min.equals(Long.MIN_VALUE) || max.equals(Long.MAX_VALUE)) { - Long[] values = parseRangeConstraint(typeToResolve, targetType, - modules, builder); + Long[] values = parseRangeConstraint(targetType, modules, + builder); if (min.equals(Long.MIN_VALUE)) { min = values[0]; LengthConstraint oldFirst = lengths.get(0); @@ -577,8 +622,7 @@ public class YangModelParserImpl implements YangModelParser { } } - private Long[] parseRangeConstraint(TypeAwareBuilder typeToResolve, - TypeDefinitionBuilder targetType, + private Long[] parseRangeConstraint(TypeDefinitionBuilder targetType, Map> modules, ModuleBuilder builder) { TypeDefinition targetBaseType = targetType.getBaseType(); @@ -596,9 +640,10 @@ public class YangModelParserImpl implements YangModelParser { Long max = (Long) ranges.get(ranges.size() - 1).getMax(); return new Long[] { min, max }; } else { - return parseRangeConstraint(typeToResolve, - findTypeDefinitionBuilder(modules, typeToResolve, builder), - modules, builder); + return parseRangeConstraint( + findTypeDefinitionBuilder(modules, + (UnknownType) targetBaseType, builder), modules, + builder); } }