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;
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;
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.DecimalTypeDefinition;
+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.parser.api.YangModelParser;
import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;
import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationTargetBuilder;
import org.opendaylight.controller.yang.model.parser.builder.api.DataSchemaNodeBuilder;
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.IdentitySchemaNodeBuilder;
import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;
+import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder;
+import org.opendaylight.controller.yang.model.parser.util.TypeConstraints;
+import org.opendaylight.controller.yang.model.parser.util.YangParseException;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
+import org.opendaylight.controller.yang.model.util.UnknownType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
.getLogger(YangModelParserImpl.class);
@Override
- public Module parseYangModel(String yangFile) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = loadFiles(yangFile);
- Set<Module> result = build(modules);
+ public Module parseYangModel(final String yangFile) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFile);
+ final Set<Module> result = build(modules);
return result.iterator().next();
}
@Override
- public Set<Module> parseYangModels(String... yangFiles) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = loadFiles(yangFiles);
- Set<Module> result = build(modules);
- return result;
+ public Set<Module> parseYangModels(final String... yangFiles) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFiles);
+ return build(modules);
+ }
+
+ @Override
+ public Set<Module> parseYangModelsFromStreams(
+ final InputStream... yangModelStreams) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangModelStreams);
+ return build(modules);
}
@Override
- public SchemaContext resolveSchemaContext(Set<Module> modules) {
+ public SchemaContext resolveSchemaContext(final Set<Module> modules) {
return new SchemaContextImpl(modules);
}
- private Map<String, TreeMap<Date, ModuleBuilder>> loadFiles(
+ private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
String... yangFiles) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
+ InputStream[] streams = new InputStream[yangFiles.length];
+ FileInputStream inStream = null;
+ for (int i = 0; i < yangFiles.length; i++) {
+ final String yangFileName = yangFiles[i];
+ final File yangFile = new File(yangFileName);
+ try {
+ inStream = new FileInputStream(yangFile);
+ } catch (FileNotFoundException e) {
+ logger.warn("Exception while reading yang stream: " + inStream,
+ e);
+ }
+ streams[i] = inStream;
+ }
+ return resolveModuleBuildersFromStreams(streams);
+ }
- final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl();
+ private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
+ InputStream... yangFiles) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
final ParseTreeWalker walker = new ParseTreeWalker();
+ final List<ParseTree> trees = parseStreams(yangFiles);
+ final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
- List<ParseTree> trees = parseFiles(yangFiles);
-
- ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
-
+ YangModelParserListenerImpl yangModelParser = null;
for (int i = 0; i < trees.size(); i++) {
+ yangModelParser = new YangModelParserListenerImpl();
walker.walk(yangModelParser, trees.get(i));
builders[i] = yangModelParser.getModuleBuilder();
}
if (builderRevision == null) {
builderRevision = createEpochTime();
}
-
TreeMap<Date, ModuleBuilder> builderByRevision = modules
.get(builderName);
if (builderByRevision == null) {
builderByRevision = new TreeMap<Date, ModuleBuilder>();
}
builderByRevision.put(builderRevision, builder);
-
modules.put(builderName, builderByRevision);
}
return modules;
}
- private List<ParseTree> parseFiles(String... yangFileNames) {
- List<ParseTree> trees = new ArrayList<ParseTree>();
- for (String fileName : yangFileNames) {
- trees.add(parseFile(fileName));
+ private List<ParseTree> parseStreams(InputStream... yangStreams) {
+ final List<ParseTree> trees = new ArrayList<ParseTree>();
+ 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;
}
private Set<Module> build(Map<String, TreeMap<Date, ModuleBuilder>> modules) {
- // first validate
+ // validate
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
.entrySet()) {
ModuleBuilder moduleBuilder = childEntry.getValue();
- validateBuilder(modules, moduleBuilder);
+ validateModule(modules, moduleBuilder);
}
}
- // then build
+
+ // build
final Set<Module> result = new HashSet<Module>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
.entrySet()) {
ModuleBuilder moduleBuilder = childEntry.getValue();
- modulesByRevision.put(childEntry.getKey(),
- moduleBuilder.build());
- result.add(moduleBuilder.build());
+ Module module = moduleBuilder.build();
+ modulesByRevision.put(childEntry.getKey(), module);
+ result.add(module);
}
}
-
return result;
}
- private void validateBuilder(
+ private void validateModule(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder builder) {
- resolveTypedefs(modules, builder);
+ resolveDirtyNodes(modules, builder);
resolveAugments(modules, builder);
+ resolveIdentities(modules, builder);
}
/**
*
* @param modules
* all available modules
- * @param builder
+ * @param module
* current module
*/
- private void resolveTypedefs(
+ private void resolveDirtyNodes(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- Map<List<String>, TypeAwareBuilder> dirtyNodes = builder
+ ModuleBuilder module) {
+ final Map<List<String>, TypeAwareBuilder> dirtyNodes = module
.getDirtyNodes();
- if (dirtyNodes.size() == 0) {
- return;
- } else {
+ if (!dirtyNodes.isEmpty()) {
for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
.entrySet()) {
+
TypeAwareBuilder typeToResolve = entry.getValue();
- Map<TypeDefinitionBuilder, TypeConstraints> 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<RangeConstraint> ranges = ut.getRangeStatements();
- resolveRanges(ranges, typeToResolve, targetType, modules,
- builder);
-
- // LENGTH
- List<LengthConstraint> lengths = ut.getLengthStatements();
- resolveLengths(lengths, typeToResolve, targetType, modules,
- builder);
-
- // PATTERN
- List<PatternConstraint> 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<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
- 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<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
- fullRanges.addAll(constraints.getRanges());
- fullRanges.addAll(ranges);
- if (typeName.startsWith("int")) {
- type = YangTypesConverter
- .javaTypeForBaseYangSignedIntegerType(typeName,
- fullRanges);
- } else {
- type = YangTypesConverter
- .javaTypeForBaseYangUnsignedIntegerType(
- typeName, fullRanges);
+ if (typeToResolve instanceof UnionTypeBuilder) {
+ UnionTypeBuilder union = (UnionTypeBuilder) typeToResolve;
+ List<TypeDefinition<?>> unionTypes = union.getTypes();
+ List<UnknownType> toRemove = new ArrayList<UnknownType>();
+ for (TypeDefinition<?> td : unionTypes) {
+ if (td instanceof UnknownType) {
+ UnknownType unknownType = (UnknownType) td;
+ TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
+ typeToResolve, unknownType, modules, module);
+ union.setType(resolvedType);
+ toRemove.add(unknownType);
+ }
}
- } else if (type instanceof StringTypeDefinition) {
- List<LengthConstraint> fullLengths = new ArrayList<LengthConstraint>();
- fullLengths.addAll(constraints.getLengths());
- fullLengths.addAll(lengths);
- List<PatternConstraint> fullPatterns = new ArrayList<PatternConstraint>();
- 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<Bit> 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);
- */
+ unionTypes.removeAll(toRemove);
+ } else {
+ TypeDefinitionBuilder resolvedType = findTargetType(
+ typeToResolve, modules, module);
+ typeToResolve.setType(resolvedType);
}
- typeToResolve.setType(type);
}
}
}
- private TypeDefinitionBuilder findTypeDefinitionBuilder(
+ private TypeDefinitionBuilder findTargetType(
+ TypeAwareBuilder typeToResolve,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- TypeAwareBuilder typeBuilder, ModuleBuilder builder) {
- Map<TypeDefinitionBuilder, TypeConstraints> result = findTypeDefinitionBuilderWithConstraints(
- modules, typeBuilder, builder);
- return result.entrySet().iterator().next().getKey();
+ ModuleBuilder builder) {
+ TypeConstraints constraints = new TypeConstraints();
+
+ TypeDefinitionBuilder targetType = findTypedef(typeToResolve, modules,
+ builder);
+ TypeConstraints tConstraints = findConstraints(typeToResolve,
+ constraints, modules, builder);
+ targetType.setRanges(tConstraints.getRange());
+ targetType.setLengths(tConstraints.getLength());
+ targetType.setPatterns(tConstraints.getPatterns());
+ targetType.setFractionDigits(tConstraints.getFractionDigits());
+
+ return targetType;
}
- private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
+ private TypeDefinitionBuilder findTargetTypeUnion(
+ TypeAwareBuilder typeToResolve, UnknownType unknownType,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- TypeAwareBuilder typeBuilder, ModuleBuilder builder) {
- return findTypeDefinitionBuilderWithConstraints(new TypeConstraints(),
- modules, typeBuilder, builder);
+ ModuleBuilder builder) {
+ TypeConstraints constraints = new TypeConstraints();
+
+ TypeDefinitionBuilder targetType = findTypedefUnion(typeToResolve,
+ unknownType, modules, builder);
+ TypeConstraints tConstraints = findConstraints(typeToResolve,
+ constraints, modules, builder);
+ targetType.setRanges(tConstraints.getRange());
+ targetType.setLengths(tConstraints.getLength());
+ targetType.setPatterns(tConstraints.getPatterns());
+ targetType.setFractionDigits(tConstraints.getFractionDigits());
+
+ return targetType;
}
- /**
- * 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
- * @return map, where key is type referenced and value is its constraints
- */
- private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
- TypeConstraints constraints,
+ private TypeDefinitionBuilder findTypedef(TypeAwareBuilder typeToResolve,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- TypeAwareBuilder typeBuilder, ModuleBuilder builder) {
- Map<TypeDefinitionBuilder, TypeConstraints> result = new HashMap<TypeDefinitionBuilder, TypeConstraints>();
+ ModuleBuilder builder) {
- UnknownType type = (UnknownType) typeBuilder.getType();
- QName typeQName = type.getQName();
- String typeName = type.getQName().getLocalName();
- String prefix = typeQName.getPrefix();
+ TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
+ if (baseTypeToResolve != null
+ && !(baseTypeToResolve instanceof UnknownType)) {
+ return (TypeDefinitionBuilder) typeToResolve;
+ }
+
+ UnknownType unknownType = (UnknownType) typeToResolve.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())) {
- dependentModuleBuilder = builder;
- } else {
- ModuleImport dependentModuleImport = getModuleImport(builder,
- prefix);
- String dependentModuleName = dependentModuleImport.getModuleName();
- Date dependentModuleRevision = dependentModuleImport.getRevision();
- TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
- .get(dependentModuleName);
- if (dependentModuleRevision == null) {
- dependentModuleBuilder = moduleBuildersByRevision.lastEntry()
- .getValue();
- } else {
- dependentModuleBuilder = moduleBuildersByRevision
- .get(dependentModuleRevision);
+ ModuleBuilder dependentModule = findDependentModule(modules, builder,
+ unknownTypePrefix);
+ TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
+ dependentModule.getModuleTypedefs(), unknownTypeName);
+
+ TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
+ lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
+ TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
+ lookedUpBuilderCopy, modules, dependentModule);
+ return resolvedCopy;
+ }
+
+ private TypeDefinitionBuilder findTypedefUnion(
+ TypeAwareBuilder typeToResolve, UnknownType unknownType,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
+ if (baseTypeToResolve != null
+ && !(baseTypeToResolve instanceof UnknownType)) {
+ return (TypeDefinitionBuilder) typeToResolve;
+ }
+
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypeName = unknownTypeQName.getLocalName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+
+ // search for module which contains referenced typedef
+ ModuleBuilder dependentModule = findDependentModule(modules, builder,
+ unknownTypePrefix);
+ TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
+ dependentModule.getModuleTypedefs(), unknownTypeName);
+
+ TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
+ lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
+ TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
+ lookedUpBuilderCopy, modules, dependentModule);
+ return resolvedCopy;
+ }
+
+ private TypeDefinitionBuilder copyTypedefBuilder(TypeDefinitionBuilder old,
+ boolean seekByTypedefBuilder) {
+ if (old instanceof UnionTypeBuilder) {
+ UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
+ UnionTypeBuilder newUnion = new UnionTypeBuilder();
+ for (TypeDefinition<?> td : oldUnion.getTypes()) {
+ newUnion.setType(td);
}
+ for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
+ newUnion.setType(copyTypedefBuilder(tdb, true));
+ }
+ return newUnion;
}
- // pull all typedef statements from dependent module...
- final Set<TypeDefinitionBuilder> typedefs = dependentModuleBuilder
- .getModuleTypedefs();
- // and search for referenced typedef
- TypeDefinitionBuilder lookedUpBuilder = null;
- for (TypeDefinitionBuilder tdb : typedefs) {
- QName qname = tdb.getQName();
- if (qname.getLocalName().equals(typeName)) {
- lookedUpBuilder = tdb;
- break;
+ QName oldQName = old.getQName();
+ QName newQName = new QName(oldQName.getNamespace(),
+ oldQName.getRevision(), oldQName.getPrefix(),
+ oldQName.getLocalName());
+ TypeDefinitionBuilder tdb = new TypedefBuilder(newQName);
+
+ tdb.setRanges(old.getRanges());
+ tdb.setLengths(old.getLengths());
+ tdb.setPatterns(old.getPatterns());
+
+ TypeDefinition<?> oldType = old.getType();
+ if (oldType == null) {
+ tdb.setType(old.getTypedef());
+ } else {
+ tdb.setType(oldType);
+ }
+
+ if (!seekByTypedefBuilder) {
+ tdb.setDescription(old.getDescription());
+ tdb.setReference(old.getReference());
+ tdb.setStatus(old.getStatus());
+ tdb.setDefaultValue(old.getDefaultValue());
+ tdb.setUnits(old.getUnits());
+ }
+ return tdb;
+ }
+
+ private TypeDefinitionBuilder resolveCopiedBuilder(
+ TypeDefinitionBuilder copied,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ if (copied instanceof UnionTypeBuilder) {
+ UnionTypeBuilder union = (UnionTypeBuilder) copied;
+ List<TypeDefinition<?>> unionTypes = union.getTypes();
+ List<UnknownType> toRemove = new ArrayList<UnknownType>();
+ for (TypeDefinition<?> td : unionTypes) {
+ if (td instanceof UnknownType) {
+ UnknownType unknownType = (UnknownType) td;
+ TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
+ union, unknownType, modules, builder);
+ union.setType(resolvedType);
+ toRemove.add(unknownType);
+ }
}
+ unionTypes.removeAll(toRemove);
+
+ return union;
+ }
+
+ TypeDefinition<?> base = copied.getType();
+ TypeDefinitionBuilder baseTdb = copied.getTypedef();
+ if (base != null && !(base instanceof UnknownType)) {
+ return copied;
+ } else if (base instanceof UnknownType) {
+ UnknownType unknownType = (UnknownType) base;
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ builder, unknownTypePrefix);
+ TypeDefinitionBuilder unknownTypeBuilder = findTypedef(copied,
+ modules, dependentModule);
+ copied.setType(unknownTypeBuilder);
+ return copied;
+ } else if (base == null && baseTdb != null) {
+ // make a copy of baseTypeDef and call again
+ TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder(baseTdb,
+ true);
+ TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
+ baseTdbCopy, modules, builder);
+ copied.setType(baseTdbCopyResolved);
+ return copied;
+ } else {
+ throw new IllegalStateException(
+ "TypeDefinitionBuilder in unexpected state");
+ }
+ }
+
+ private TypeDefinitionBuilder findTypedef(QName unknownTypeQName,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ String unknownTypeName = unknownTypeQName.getLocalName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+
+ // search for module which contains referenced typedef
+ ModuleBuilder dependentModule = findDependentModule(modules, builder,
+ unknownTypePrefix);
+
+ TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
+ dependentModule.getModuleTypedefs(), unknownTypeName);
+
+ TypeDefinitionBuilder copied = copyTypedefBuilder(lookedUpBuilder, true);
+ return copied;
+ }
+
+ private TypeConstraints findConstraints(TypeAwareBuilder typeToResolve,
+ TypeConstraints constraints,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ // union type cannot be restricted
+ if (typeToResolve instanceof UnionTypeBuilder) {
+ return constraints;
}
// if referenced type is UnknownType again, search recursively with
// current constraints
- TypeDefinition<?> referencedType = lookedUpBuilder.getBaseType();
- if (referencedType instanceof UnknownType) {
- UnknownType unknown = (UnknownType) lookedUpBuilder.getBaseType();
+ TypeDefinition<?> referencedType = typeToResolve.getType();
+ if (referencedType == null) {
+ TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) typeToResolve;
+ final List<RangeConstraint> ranges = tdb.getRanges();
+ constraints.addRanges(ranges);
+ final List<LengthConstraint> lengths = tdb.getLengths();
+ constraints.addLengths(lengths);
+ final List<PatternConstraint> patterns = tdb.getPatterns();
+ constraints.addPatterns(patterns);
+ final Integer fractionDigits = tdb.getFractionDigits();
+ constraints.setFractionDigits(fractionDigits);
+ return constraints;
+ } else if (referencedType instanceof ExtendedType) {
+ ExtendedType ext = (ExtendedType) referencedType;
+ final List<RangeConstraint> ranges = ext.getRanges();
+ constraints.addRanges(ranges);
+ final List<LengthConstraint> lengths = ext.getLengths();
+ constraints.addLengths(lengths);
+ final List<PatternConstraint> patterns = ext.getPatterns();
+ constraints.addPatterns(patterns);
+ final Integer fractionDigits = ext.getFractionDigits();
+ constraints.setFractionDigits(fractionDigits);
+ return findConstraints(
+ findTypedef(ext.getQName(), modules, builder), constraints,
+ modules, builder);
+ } else if (referencedType instanceof UnknownType) {
+ UnknownType unknown = (UnknownType) referencedType;
final List<RangeConstraint> ranges = unknown.getRangeStatements();
constraints.addRanges(ranges);
constraints.addLengths(lengths);
final List<PatternConstraint> patterns = unknown.getPatterns();
constraints.addPatterns(patterns);
- return findTypeDefinitionBuilderWithConstraints(constraints,
- modules, (TypeAwareBuilder) lookedUpBuilder,
- dependentModuleBuilder);
+ final Integer fractionDigits = unknown.getFractionDigits();
+ constraints.setFractionDigits(fractionDigits);
+
+ String unknownTypePrefix = unknown.getQName().getPrefix();
+ if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) {
+ unknownTypePrefix = builder.getPrefix();
+ }
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ builder, unknown.getQName().getPrefix());
+ TypeDefinitionBuilder unknownTypeBuilder = findTypedef(
+ unknown.getQName(), modules, builder);
+ return findConstraints(unknownTypeBuilder, constraints, modules,
+ dependentModule);
} else {
- // pull restriction from this base type and add them to
- // 'constraints'
- if (referencedType instanceof DecimalTypeDefinition) {
- constraints.addRanges(((DecimalTypeDefinition) referencedType)
- .getRangeStatements());
- constraints
- .setFractionDigits(((DecimalTypeDefinition) referencedType)
- .getFractionDigits());
- } else if (referencedType instanceof IntegerTypeDefinition) {
- constraints.addRanges(((IntegerTypeDefinition) referencedType)
- .getRangeStatements());
- } 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
- } else if (referencedType instanceof InstanceIdentifierTypeDefinition) {
- // TODO: instance-identifier
+ // HANDLE BASE YANG TYPE
+ mergeConstraints(referencedType, constraints);
+ return constraints;
+ }
+
+ }
+
+ /**
+ * Go through all typedef statements from given module and search for one
+ * with given name
+ *
+ * @param typedefs
+ * typedef statements to search
+ * @param name
+ * name of searched typedef
+ * @return typedef with name equals to given name
+ */
+ private TypeDefinitionBuilder findTypedefBuilder(
+ Set<TypeDefinitionBuilder> typedefs, String name) {
+ TypeDefinitionBuilder result = null;
+ for (TypeDefinitionBuilder td : typedefs) {
+ if (td.getQName().getLocalName().equals(name)) {
+ result = td;
+ break;
}
+ }
+ if (result == null) {
+ throw new YangParseException(
+ "Target module does not contain typedef '" + name + "'.");
+ }
+ return result;
+ }
- result.put(lookedUpBuilder, constraints);
- // return lookedUpBuilder;
- return result;
+ /**
+ * Pull restriction from referenced type and add them to given constraints
+ *
+ * @param referencedType
+ * @param constraints
+ */
+ private void mergeConstraints(TypeDefinition<?> referencedType,
+ TypeConstraints constraints) {
+
+ if (referencedType instanceof DecimalTypeDefinition) {
+ constraints.addRanges(((DecimalTypeDefinition) referencedType)
+ .getRangeStatements());
+ constraints
+ .setFractionDigits(((DecimalTypeDefinition) referencedType)
+ .getFractionDigits());
+ } else if (referencedType instanceof IntegerTypeDefinition) {
+ constraints.addRanges(((IntegerTypeDefinition) referencedType)
+ .getRangeStatements());
+ } else if (referencedType instanceof StringTypeDefinition) {
+ constraints.addPatterns(((StringTypeDefinition) referencedType)
+ .getPatterns());
+ constraints.addLengths(((StringTypeDefinition) referencedType)
+ .getLengthStatements());
+ } else if (referencedType instanceof BinaryTypeDefinition) {
+ constraints.addLengths(((BinaryTypeDefinition) referencedType)
+ .getLengthConstraints());
}
}
*
* @param modules
* all available modules
- * @param builder
+ * @param module
* current module
*/
private void resolveAugments(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- Set<AugmentationSchemaBuilder> augmentBuilders = builder
+ ModuleBuilder module) {
+ Set<AugmentationSchemaBuilder> augmentBuilders = module
.getAddedAugments();
Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();
SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
String prefix = null;
List<String> augmentTargetPath = new ArrayList<String>();
+
for (QName pathPart : augmentTargetSchemaPath.getPath()) {
prefix = pathPart.getPrefix();
augmentTargetPath.add(pathPart.getLocalName());
}
- ModuleImport dependentModuleImport = getModuleImport(builder,
- prefix);
- String dependentModuleName = dependentModuleImport.getModuleName();
- augmentTargetPath.add(0, dependentModuleName);
-
- Date dependentModuleRevision = dependentModuleImport.getRevision();
-
- TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
- .get(dependentModuleName);
- ModuleBuilder dependentModule;
- if (dependentModuleRevision == null) {
- dependentModule = moduleBuildersByRevision.lastEntry()
- .getValue();
- } else {
- dependentModule = moduleBuildersByRevision
- .get(dependentModuleRevision);
- }
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ module, prefix);
+ augmentTargetPath.add(0, dependentModule.getName());
AugmentationTargetBuilder augmentTarget = (AugmentationTargetBuilder) dependentModule
.getNode(augmentTargetPath);
fillAugmentTarget(augmentBuilder, (ChildNodeBuilder) augmentTarget);
augments.add(result);
}
- builder.setAugmentations(augments);
+ module.setAugmentations(augments);
}
/**
}
/**
- * Get module import referenced by given prefix.
+ * Go through identity statements defined in current module and resolve
+ * their 'base' statement if present.
*
- * @param builder
- * module to search
- * @param prefix
- * prefix associated with import
- * @return ModuleImport based on given prefix
+ * @param modules
+ * all modules
+ * @param module
+ * module being resolved
*/
- private ModuleImport getModuleImport(ModuleBuilder builder, String prefix) {
- ModuleImport moduleImport = null;
- for (ModuleImport mi : builder.getModuleImports()) {
- if (mi.getPrefix().equals(prefix)) {
- moduleImport = mi;
- break;
+ private void resolveIdentities(
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder module) {
+ Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
+ for (IdentitySchemaNodeBuilder identity : identities) {
+ String baseIdentityName = identity.getBaseIdentityName();
+ if (baseIdentityName != null) {
+ String baseIdentityPrefix = null;
+ String baseIdentityLocalName = null;
+ if (baseIdentityName.contains(":")) {
+ String[] splitted = baseIdentityName.split(":");
+ baseIdentityPrefix = splitted[0];
+ baseIdentityLocalName = splitted[1];
+ } else {
+ baseIdentityPrefix = module.getPrefix();
+ baseIdentityLocalName = baseIdentityName;
+ }
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ module, baseIdentityPrefix);
+
+ Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule
+ .getAddedIdentities();
+ for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
+ if (idBuilder.getQName().getLocalName()
+ .equals(baseIdentityLocalName)) {
+ identity.setBaseIdentity(idBuilder);
+ }
+ }
}
}
- return moduleImport;
}
/**
- * Helper method for resolving special 'min' or 'max' values in range
- * constraint
+ * Find dependent module based on given prefix
*
- * @param ranges
- * ranges to resolve
- * @param typeToResolve
- * type to resolve
- * @param targetType
- * target type
* @param modules
* all available modules
- * @param builder
+ * @param module
* current module
+ * @param prefix
+ * target module prefix
+ * @return
*/
- private void resolveRanges(List<RangeConstraint> ranges,
- TypeAwareBuilder typeToResolve, TypeDefinitionBuilder targetType,
+ private ModuleBuilder findDependentModule(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- if (ranges != null && ranges.size() > 0) {
- Long min = (Long) ranges.get(0).getMin();
- 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);
- if (min.equals(Long.MIN_VALUE)) {
- min = values[0];
- RangeConstraint oldFirst = ranges.get(0);
- RangeConstraint newFirst = BaseConstraints.rangeConstraint(
- min, oldFirst.getMax(), oldFirst.getDescription(),
- oldFirst.getReference());
- ranges.set(0, newFirst);
- }
- if (max.equals(Long.MAX_VALUE)) {
- max = values[1];
- RangeConstraint oldLast = ranges.get(ranges.size() - 1);
- RangeConstraint newLast = BaseConstraints.rangeConstraint(
- oldLast.getMin(), max, oldLast.getDescription(),
- oldLast.getReference());
- ranges.set(ranges.size() - 1, newLast);
- }
+ ModuleBuilder module, String prefix) {
+ ModuleBuilder dependentModule = null;
+ Date dependentModuleRevision = null;
+
+ if (prefix.equals(module.getPrefix())) {
+ dependentModule = module;
+ } else {
+ ModuleImport dependentModuleImport = getModuleImport(module, prefix);
+ if (dependentModuleImport == null) {
+ throw new YangParseException("No import found with prefix '"
+ + prefix + "' in module " + module.getName() + "'.");
+ }
+ String dependentModuleName = dependentModuleImport.getModuleName();
+ dependentModuleRevision = dependentModuleImport.getRevision();
+
+ TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
+ .get(dependentModuleName);
+ if (dependentModuleRevision == null) {
+ dependentModule = moduleBuildersByRevision.lastEntry()
+ .getValue();
+ } else {
+ dependentModule = moduleBuildersByRevision
+ .get(dependentModuleRevision);
}
}
+
+ if (dependentModule == null) {
+ throw new YangParseException(
+ "Failed to find dependent module with prefix '" + prefix
+ + "' and revision '" + dependentModuleRevision
+ + "'.");
+ }
+ return dependentModule;
}
/**
- * Helper method for resolving special 'min' or 'max' values in length
- * constraint
+ * Get module import referenced by given prefix.
*
- * @param ranges
- * ranges to resolve
- * @param typeToResolve
- * type to resolve
- * @param targetType
- * target type
- * @param modules
- * all available modules
* @param builder
- * current module
+ * module to search
+ * @param prefix
+ * prefix associated with import
+ * @return ModuleImport based on given prefix
*/
- private void resolveLengths(List<LengthConstraint> lengths,
- TypeAwareBuilder typeToResolve, TypeDefinitionBuilder targetType,
- Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- if (lengths != null && lengths.size() > 0) {
- Long min = lengths.get(0).getMin();
- 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);
- if (min.equals(Long.MIN_VALUE)) {
- min = values[0];
- LengthConstraint oldFirst = lengths.get(0);
- LengthConstraint newFirst = BaseConstraints
- .lengthConstraint(min, oldFirst.getMax(),
- oldFirst.getDescription(),
- oldFirst.getReference());
- lengths.set(0, newFirst);
- }
- if (max.equals(Long.MAX_VALUE)) {
- max = values[1];
- LengthConstraint oldLast = lengths.get(lengths.size() - 1);
- LengthConstraint newLast = BaseConstraints
- .lengthConstraint(oldLast.getMin(), max,
- oldLast.getDescription(),
- oldLast.getReference());
- lengths.set(lengths.size() - 1, newLast);
- }
+ private ModuleImport getModuleImport(ModuleBuilder builder, String prefix) {
+ ModuleImport moduleImport = null;
+ for (ModuleImport mi : builder.getModuleImports()) {
+ if (mi.getPrefix().equals(prefix)) {
+ moduleImport = mi;
+ break;
}
}
- }
-
- private Long[] parseRangeConstraint(TypeAwareBuilder typeToResolve,
- TypeDefinitionBuilder targetType,
- Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- TypeDefinition<?> targetBaseType = targetType.getBaseType();
-
- if (targetBaseType instanceof IntegerTypeDefinition) {
- IntegerTypeDefinition itd = (IntegerTypeDefinition) targetBaseType;
- List<RangeConstraint> ranges = itd.getRangeStatements();
- Long min = (Long) ranges.get(0).getMin();
- Long max = (Long) ranges.get(ranges.size() - 1).getMax();
- return new Long[] { min, max };
- } else if (targetBaseType instanceof DecimalTypeDefinition) {
- DecimalTypeDefinition dtd = (DecimalTypeDefinition) targetBaseType;
- List<RangeConstraint> ranges = dtd.getRangeStatements();
- Long min = (Long) ranges.get(0).getMin();
- 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 moduleImport;
}
private Date createEpochTime() {
- Calendar c = Calendar.getInstance();
- c.setTimeInMillis(0);
- return c.getTime();
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(0);
+ return calendar.getTime();
}
private static class SchemaContextImpl implements SchemaContext {
}
}
- private static class TypeConstraints {
- private final List<RangeConstraint> ranges = new ArrayList<RangeConstraint>();
- private final List<LengthConstraint> lengths = new ArrayList<LengthConstraint>();
- private final List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
- private Integer fractionDigits;
-
- public List<RangeConstraint> getRanges() {
- return ranges;
- }
-
- public void addRanges(List<RangeConstraint> ranges) {
- this.ranges.addAll(0, ranges);
- }
-
- public List<LengthConstraint> getLengths() {
- return lengths;
- }
-
- public void addLengths(List<LengthConstraint> lengths) {
- this.lengths.addAll(0, lengths);
- }
-
- public List<PatternConstraint> getPatterns() {
- return patterns;
- }
-
- public void addPatterns(List<PatternConstraint> patterns) {
- this.patterns.addAll(0, patterns);
- }
-
- public Integer getFractionDigits() {
- return fractionDigits;
- }
-
- public void setFractionDigits(Integer fractionDigits) {
- if (fractionDigits != null) {
- this.fractionDigits = fractionDigits;
- }
- }
- }
-
}