YANG model parser refactoring 26/126/3
authorMartin Vitez <mvitez@cisco.com>
Mon, 8 Apr 2013 08:31:04 +0000 (10:31 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 13 Apr 2013 02:59:40 +0000 (02:59 +0000)
-fix YANG types constraints resolving
-added tests
-removed unused test files

Signed-off-by: Martin Vitez <mvitez@cisco.com>
17 files changed:
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/builder/impl/ExtensionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserListenerImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/TypeConstraints.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/UnknownBoundaryNumber.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangModelBuilderUtil.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangParseException.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/model/parser/impl/TypesResolutionTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/model/parser/impl/YangModelParserTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/testfile1.yang
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/testfile2.yang
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang1.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang2.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang3.yang [deleted file]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/type/LengthConstraint.java
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/BaseConstraints.java
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/StringType.java

index fa5c495..28a2330 100644 (file)
@@ -48,6 +48,10 @@ public class ExtensionBuilder implements SchemaNodeBuilder {
         instance.setYinElement(yin);
     }
 
+    public void setArgument(String argument) {
+        instance.setArgument(argument);
+    }
+
     @Override
     public QName getQName() {
         return qname;
@@ -80,6 +84,7 @@ public class ExtensionBuilder implements SchemaNodeBuilder {
 
     private static class ExtensionDefinitionImpl implements ExtensionDefinition {
         private final QName qname;
+        private String argument;
         private SchemaPath schemaPath;
         private String description;
         private String reference;
@@ -149,7 +154,11 @@ public class ExtensionBuilder implements SchemaNodeBuilder {
 
         @Override
         public String getArgument() {
-            return qname.getLocalName();
+            return argument;
+        }
+
+        private void setArgument(String argument) {
+            this.argument = argument;
         }
 
         @Override
@@ -247,7 +256,8 @@ public class ExtensionBuilder implements SchemaNodeBuilder {
             StringBuilder sb = new StringBuilder(
                     ExtensionDefinitionImpl.class.getSimpleName());
             sb.append("[");
-            sb.append("qname=" + qname);
+            sb.append("argument="+ argument);
+            sb.append(", qname=" + qname);
             sb.append(", schemaPath=" + schemaPath);
             sb.append(", description=" + description);
             sb.append(", reference=" + reference);
index f30780f..81a5c97 100644 (file)
@@ -14,6 +14,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -58,7 +59,8 @@ import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionB
 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.UnionTypeBuilder;
-import org.opendaylight.controller.yang.model.util.BaseConstraints;
+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.BinaryType;
 import org.opendaylight.controller.yang.model.util.BitsType;
 import org.opendaylight.controller.yang.model.util.StringType;
@@ -120,15 +122,12 @@ public class YangModelParserImpl implements YangModelParser {
     private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
             InputStream... yangFiles) {
         final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
-
-        final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl();
         final ParseTreeWalker walker = new ParseTreeWalker();
-
-        List<ParseTree> trees = parseStreams(yangFiles);
-
-        ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
+        final List<ParseTree> trees = parseStreams(yangFiles);
+        final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
 
         for (int i = 0; i < trees.size(); i++) {
+            final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl();
             walker.walk(yangModelParser, trees.get(i));
             builders[i] = yangModelParser.getModuleBuilder();
         }
@@ -173,7 +172,7 @@ public class YangModelParserImpl implements YangModelParser {
     }
 
     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()
@@ -182,7 +181,7 @@ public class YangModelParserImpl implements YangModelParser {
                 validateBuilder(modules, moduleBuilder);
             }
         }
-        // then build
+        // build
         final Set<Module> result = new HashSet<Module>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
                 .entrySet()) {
@@ -267,104 +266,31 @@ public class YangModelParserImpl implements YangModelParser {
             Map<String, TreeMap<Date, ModuleBuilder>> modules,
             ModuleBuilder builder) {
 
-        Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
-                modules, ut, builder);
-        TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
-                .entrySet().iterator().next().getKey();
-        TypeConstraints constraints = foundedTypeDefinitionBuilder.entrySet()
-                .iterator().next().getValue();
-
-        TypeDefinition<?> targetTypeBaseType = targetType.getBaseType();
-
+        TypeConstraints constraints = new TypeConstraints();
         // RANGE
         List<RangeConstraint> ranges = ut.getRangeStatements();
-        resolveRanges(ranges, targetType, modules, builder);
+        constraints.addRanges(ranges);
         // LENGTH
         List<LengthConstraint> lengths = ut.getLengthStatements();
-        resolveLengths(lengths, targetType, modules, builder);
+        constraints.addLengths(lengths);
         // PATTERN
         List<PatternConstraint> patterns = ut.getPatterns();
+        constraints.addPatterns(patterns);
         // Fraction Digits
         Integer fractionDigits = ut.getFractionDigits();
 
-        targetTypeBaseType = mergeConstraints(targetTypeBaseType, constraints, ranges, lengths,
-                patterns, fractionDigits);
+        Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
+                constraints, modules, ut, builder);
+        TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
+                .entrySet().iterator().next().getKey();
 
-        return targetTypeBaseType;
-    }
+        TypeDefinition<?> targetTypeBaseType = targetType.getBaseType();
+        targetTypeBaseType = mergeConstraints(targetTypeBaseType, constraints,
+                fractionDigits);
 
-    /**
-     * Merge curent constraints with founded type constraints
-     *
-     * @param targetTypeBaseType
-     * @param constraints
-     * @param ranges
-     * @param lengths
-     * @param patterns
-     * @param fractionDigits
-     */
-    private TypeDefinition<?> mergeConstraints(TypeDefinition<?> targetTypeBaseType,
-            TypeConstraints constraints, List<RangeConstraint> ranges,
-            List<LengthConstraint> lengths, List<PatternConstraint> patterns,
-            Integer fractionDigits) {
-        String targetTypeBaseTypeName = targetTypeBaseType.getQName()
-                .getLocalName();
-        // enumeration, leafref and identityref omitted because they have no
-        // restrictions
-        if (targetTypeBaseType instanceof DecimalTypeDefinition) {
-            List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
-            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<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
-            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<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);
-            targetTypeBaseType = new StringType(fullLengths, fullPatterns);
-        } else if (targetTypeBaseType instanceof BitsTypeDefinition) {
-            BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType;
-            List<Bit> bits = bitsType.getBits();
-            targetTypeBaseType = new BitsType(bits);
-        } else if (targetTypeBaseType instanceof BinaryTypeDefinition) {
-            targetTypeBaseType = new BinaryType(null, lengths, null);
-        }
         return targetTypeBaseType;
     }
 
-    private TypeDefinitionBuilder findTypeDefinitionBuilder(
-            Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            UnknownType unknownType, ModuleBuilder builder) {
-        Map<TypeDefinitionBuilder, TypeConstraints> result = findTypeDefinitionBuilderWithConstraints(
-                modules, unknownType, builder);
-        return result.entrySet().iterator().next().getKey();
-    }
-
-    private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
-            Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            UnknownType unknownType, ModuleBuilder builder) {
-        return findTypeDefinitionBuilderWithConstraints(new TypeConstraints(),
-                modules, unknownType, builder);
-    }
-
     /**
      * Traverse through all referenced types chain until base YANG type is
      * founded.
@@ -389,32 +315,17 @@ public class YangModelParserImpl implements YangModelParser {
         String unknownTypePrefix = unknownTypeQName.getPrefix();
 
         // search for module which contains referenced typedef
-        ModuleBuilder dependentModuleBuilder;
-        if (unknownTypePrefix.equals(builder.getPrefix())) {
-            dependentModuleBuilder = builder;
-        } else {
-            dependentModuleBuilder = findDependentModule(modules, builder,
-                    unknownTypePrefix);
-        }
+        ModuleBuilder dependentModuleBuilder = findDependentModule(modules,
+                builder, unknownTypePrefix);
 
-        // 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(unknownTypeName)) {
-                lookedUpBuilder = tdb;
-                break;
-            }
-        }
+        TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
+                dependentModuleBuilder.getModuleTypedefs(), unknownTypeName);
 
         // if referenced type is UnknownType again, search recursively with
         // current constraints
         TypeDefinition<?> referencedType = lookedUpBuilder.getBaseType();
         if (referencedType instanceof UnknownType) {
-            UnknownType unknown = (UnknownType) lookedUpBuilder.getBaseType();
+            UnknownType unknown = (UnknownType) referencedType;
 
             final List<RangeConstraint> ranges = unknown.getRangeStatements();
             constraints.addRanges(ranges);
@@ -426,29 +337,115 @@ public class YangModelParserImpl implements YangModelParser {
             return findTypeDefinitionBuilderWithConstraints(constraints,
                     modules, unknown, dependentModuleBuilder);
         } 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 BinaryTypeDefinition) {
-                constraints.addLengths(((BinaryTypeDefinition) referencedType)
-                        .getLengthConstraints());
-            }
+            mergeConstraints(referencedType, constraints);
             result.put(lookedUpBuilder, constraints);
             return result;
         }
     }
 
+    /**
+     * 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;
+    }
+
+    /**
+     * Merge curent constraints with founded type constraints
+     *
+     * @param targetTypeBaseType
+     * @param constraints
+     * @param fractionDigits
+     * @return
+     */
+    private TypeDefinition<?> mergeConstraints(
+            TypeDefinition<?> targetTypeBaseType, TypeConstraints constraints,
+            Integer fractionDigits) {
+        String targetTypeBaseTypeName = targetTypeBaseType.getQName()
+                .getLocalName();
+        // enumeration, leafref and identityref omitted because they have no
+        // restrictions
+        if (targetTypeBaseType instanceof DecimalTypeDefinition) {
+            List<RangeConstraint> ranges = constraints.getRange();
+            Integer fd = fractionDigits == null ? constraints
+                    .getFractionDigits() : fractionDigits;
+            targetTypeBaseType = YangTypesConverter
+                    .javaTypeForBaseYangDecimal64Type(ranges, fd);
+        } else if (targetTypeBaseType instanceof IntegerTypeDefinition) {
+            List<RangeConstraint> ranges = constraints.getRange();
+            if (targetTypeBaseTypeName.startsWith("int")) {
+                targetTypeBaseType = YangTypesConverter
+                        .javaTypeForBaseYangSignedIntegerType(
+                                targetTypeBaseTypeName, ranges);
+            } else {
+                targetTypeBaseType = YangTypesConverter
+                        .javaTypeForBaseYangUnsignedIntegerType(
+                                targetTypeBaseTypeName, ranges);
+            }
+        } else if (targetTypeBaseType instanceof StringTypeDefinition) {
+            List<LengthConstraint> lengths = constraints.getLength();
+            List<PatternConstraint> patterns = constraints.getPatterns();
+            targetTypeBaseType = new StringType(lengths, patterns);
+        } else if (targetTypeBaseType instanceof BitsTypeDefinition) {
+            BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType;
+            List<Bit> bits = bitsType.getBits();
+            targetTypeBaseType = new BitsType(bits);
+        } else if (targetTypeBaseType instanceof BinaryTypeDefinition) {
+            List<LengthConstraint> lengths = constraints.getLength();
+            List<Byte> bytes = Collections.emptyList();
+            targetTypeBaseType = new BinaryType(bytes, lengths, null);
+        }
+        return targetTypeBaseType;
+    }
+
+    /**
+     * Pull restriction from base 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());
+        }
+    }
+
     /**
      * Go through all augmentation definitions and resolve them. This means find
      * referenced node and add child nodes to it.
@@ -476,10 +473,7 @@ public class YangModelParserImpl implements YangModelParser {
             }
             ModuleBuilder dependentModule = findDependentModule(modules,
                     module, prefix);
-            //
             augmentTargetPath.add(0, dependentModule.getName());
-            //
-
 
             AugmentationTargetBuilder augmentTarget = (AugmentationTargetBuilder) dependentModule
                     .getNode(augmentTargetPath);
@@ -531,13 +525,8 @@ public class YangModelParserImpl implements YangModelParser {
                     baseIdentityPrefix = module.getPrefix();
                     baseIdentityLocalName = baseIdentityName;
                 }
-                ModuleBuilder dependentModule;
-                if (baseIdentityPrefix.equals(module.getPrefix())) {
-                    dependentModule = module;
-                } else {
-                    dependentModule = findDependentModule(modules, module,
-                            baseIdentityPrefix);
-                }
+                ModuleBuilder dependentModule = findDependentModule(modules,
+                        module, baseIdentityPrefix);
 
                 Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule
                         .getAddedIdentities();
@@ -560,23 +549,41 @@ public class YangModelParserImpl implements YangModelParser {
      *            current module
      * @param prefix
      *            target module prefix
-     * @return dependent module builder
+     * @return
      */
     private ModuleBuilder findDependentModule(
             Map<String, TreeMap<Date, ModuleBuilder>> modules,
             ModuleBuilder module, String prefix) {
-        ModuleImport dependentModuleImport = getModuleImport(module, prefix);
-        String dependentModuleName = dependentModuleImport.getModuleName();
-        Date dependentModuleRevision = dependentModuleImport.getRevision();
-
-        TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
-                .get(dependentModuleName);
-        ModuleBuilder dependentModule;
-        if (dependentModuleRevision == null) {
-            dependentModule = moduleBuildersByRevision.lastEntry().getValue();
+        ModuleBuilder dependentModule = null;
+        Date dependentModuleRevision = null;
+
+        if (prefix.equals(module.getPrefix())) {
+            dependentModule = module;
         } else {
-            dependentModule = moduleBuildersByRevision
-                    .get(dependentModuleRevision);
+            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;
     }
@@ -601,121 +608,6 @@ public class YangModelParserImpl implements YangModelParser {
         return moduleImport;
     }
 
-    /**
-     * Helper method for resolving special 'min' or 'max' values in range
-     * constraint
-     *
-     * @param ranges
-     *            ranges to resolve
-     * @param targetType
-     *            target type
-     * @param modules
-     *            all available modules
-     * @param builder
-     *            current module
-     */
-    private void resolveRanges(List<RangeConstraint> ranges,
-            TypeDefinitionBuilder targetType,
-            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(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);
-                }
-            }
-        }
-    }
-
-    /**
-     * Helper method for resolving special 'min' or 'max' values in length
-     * constraint
-     *
-     * @param lengths
-     *            lengths to resolve
-     * @param targetType
-     *            target type
-     * @param modules
-     *            all available modules
-     * @param builder
-     *            current module
-     */
-    private void resolveLengths(List<LengthConstraint> lengths,
-            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(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 Long[] parseRangeConstraint(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(
-                    findTypeDefinitionBuilder(modules,
-                            (UnknownType) targetBaseType, builder), modules,
-                    builder);
-        }
-    }
-
     private Date createEpochTime() {
         Calendar c = Calendar.getInstance();
         c.setTimeInMillis(0);
@@ -771,45 +663,4 @@ public class YangModelParserImpl implements YangModelParser {
         }
     }
 
-    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;
-            }
-        }
-    }
-
 }
index 7e64c6e..6e62065 100644 (file)
@@ -13,7 +13,6 @@ import java.net.URI;
 import java.text.DateFormat;\r
 import java.text.ParseException;\r
 import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.Date;\r
 import java.util.List;\r
@@ -22,6 +21,7 @@ import java.util.TreeMap;
 \r
 import org.antlr.v4.runtime.tree.ParseTree;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Argument_stmtContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Base_stmtContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Contact_stmtContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Container_stmtContext;\r
@@ -47,7 +47,6 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtCont
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtsContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;\r
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Union_specificationContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;\r
 import org.opendaylight.controller.antlrv4.code.gen.YangParserBaseListener;\r
 import org.opendaylight.controller.yang.common.QName;\r
@@ -188,6 +187,7 @@ final class YangModelParserListenerImpl extends YangParserBaseListener {
         if(revisions.size() > 0) {\r
             Revision_stmtContext revisionCtx = revisions.firstEntry().getValue();\r
             moduleBuilder.setRevision(revisions.firstKey());\r
+            revision = revisions.firstKey();\r
 \r
             for(int i = 0; i < revisionCtx.getChildCount(); i++) {\r
                 ParseTree child = revisionCtx.getChild(i);\r
@@ -253,10 +253,23 @@ final class YangModelParserListenerImpl extends YangParserBaseListener {
 \r
     @Override\r
     public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
-        String argument = stringFromNode(ctx);\r
-        QName qname = new QName(namespace, revision, yangModelPrefix, argument);\r
+        String extName = stringFromNode(ctx);\r
+        QName qname = new QName(namespace, revision, yangModelPrefix, extName);\r
         ExtensionBuilder builder = moduleBuilder.addExtension(qname);\r
         parseSchemaNodeArgs(ctx, builder);\r
+\r
+        String argument = null;\r
+        boolean yin = false;\r
+        for(int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if(child instanceof Argument_stmtContext) {\r
+                argument = stringFromNode(child);\r
+                yin = parseYinValue((Argument_stmtContext)child);\r
+                break;\r
+            }\r
+        }\r
+        builder.setArgument(argument);\r
+        builder.setYinElement(yin);\r
     }\r
 \r
     @Override\r
@@ -283,20 +296,7 @@ final class YangModelParserListenerImpl extends YangParserBaseListener {
     @Override\r
     public void enterType_stmt(YangParser.Type_stmtContext ctx) {\r
         String typeName = stringFromNode(ctx);\r
-        QName typeQName;\r
-        if (typeName.contains(":")) {\r
-            String[] splittedName = typeName.split(":");\r
-            String prefix = splittedName[0];\r
-            String name = splittedName[1];\r
-            if (prefix.equals(yangModelPrefix)) {\r
-                typeQName = new QName(namespace, revision, prefix, name);\r
-            } else {\r
-                typeQName = new QName(null, null, prefix, name);\r
-            }\r
-        } else {\r
-            typeQName = new QName(namespace, revision, yangModelPrefix,\r
-                    typeName);\r
-        }\r
+        QName typeQName = parseQName(typeName);\r
 \r
         TypeDefinition<?> type = null;\r
         Type_body_stmtsContext typeBody = null;\r
@@ -315,16 +315,6 @@ final class YangModelParserListenerImpl extends YangParserBaseListener {
                 moduleBuilder.setType(type, actualPath);\r
             } else {\r
                 if(typeName.equals("union")) {\r
-                    List<String> types = new ArrayList<String>();\r
-                    for(int i = 0; i < typeBody.getChildCount(); i++) {\r
-                        ParseTree unionSpec = typeBody.getChild(i);\r
-                        if(unionSpec instanceof Union_specificationContext) {\r
-                            for(int j = 0; j < unionSpec.getChildCount(); j++) {\r
-                                ParseTree typeSpec = unionSpec.getChild(j);\r
-                                types.add(stringFromNode(typeSpec));\r
-                            }\r
-                        }\r
-                    }\r
                     moduleBuilder.addUnionType(actualPath);\r
                 } else {\r
                     type = parseTypeBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix);\r
@@ -339,7 +329,24 @@ final class YangModelParserListenerImpl extends YangParserBaseListener {
         }\r
 \r
         updatePath(typeName);\r
+    }\r
 \r
+    private QName parseQName(String typeName) {\r
+        QName typeQName;\r
+        if (typeName.contains(":")) {\r
+            String[] splittedName = typeName.split(":");\r
+            String prefix = splittedName[0];\r
+            String name = splittedName[1];\r
+            if (prefix.equals(yangModelPrefix)) {\r
+                typeQName = new QName(namespace, revision, prefix, name);\r
+            } else {\r
+                typeQName = new QName(null, null, prefix, name);\r
+            }\r
+        } else {\r
+            typeQName = new QName(namespace, revision, yangModelPrefix,\r
+                    typeName);\r
+        }\r
+        return typeQName;\r
     }\r
 \r
     @Override\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/TypeConstraints.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/TypeConstraints.java
new file mode 100644 (file)
index 0000000..9e5fcbe
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.model.parser.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.util.BaseConstraints;
+
+/**
+ * Holder object for holding YANG type constraints.
+ */
+public final class TypeConstraints {
+    private final List<List<RangeConstraint>> ranges = new ArrayList<List<RangeConstraint>>();
+    private final List<List<LengthConstraint>> lengths = new ArrayList<List<LengthConstraint>>();
+    private final List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
+    private Integer fractionDigits;
+
+    List<List<RangeConstraint>> getAllRanges() {
+        return ranges;
+    }
+
+    public List<RangeConstraint> getRange() {
+        List<RangeConstraint> resolved = ranges.get(0);
+        RangeConstraint firstRange = resolved.get(0);
+        RangeConstraint lastRange = resolved.get(resolved.size() - 1);
+        Number min = firstRange.getMin();
+        Number max = lastRange.getMax();
+
+        if (!(min instanceof UnknownBoundaryNumber)
+                && !(max instanceof UnknownBoundaryNumber)) {
+            return resolved;
+        }
+
+        if (firstRange == lastRange) {
+            if (min instanceof UnknownBoundaryNumber) {
+                min = resolveMinRange(min);
+            }
+            if (max instanceof UnknownBoundaryNumber) {
+                max = resolveMaxRange(max);
+            }
+            firstRange = BaseConstraints.rangeConstraint(min, max,
+                    firstRange.getDescription(), firstRange.getReference());
+            resolved.set(0, firstRange);
+            lastRange = BaseConstraints.rangeConstraint(min, max,
+                    lastRange.getDescription(), lastRange.getReference());
+            resolved.set(resolved.size() - 1, lastRange);
+        } else {
+            if (min instanceof UnknownBoundaryNumber) {
+                min = resolveMinRange(min);
+                firstRange = BaseConstraints.rangeConstraint(min,
+                        firstRange.getMax(), firstRange.getDescription(),
+                        firstRange.getReference());
+                resolved.set(0, firstRange);
+            }
+            if (max instanceof UnknownBoundaryNumber) {
+                max = resolveMaxRange(max);
+                lastRange = BaseConstraints.rangeConstraint(lastRange.getMin(),
+                        max, lastRange.getDescription(),
+                        lastRange.getReference());
+                resolved.set(resolved.size() - 1, lastRange);
+            }
+        }
+        return resolved;
+    }
+
+    private Number resolveMinRange(Number min) {
+        int i = 1;
+        while (min instanceof UnknownBoundaryNumber) {
+            List<RangeConstraint> act = ranges.get(i);
+            min = act.get(0).getMin();
+            i++;
+        }
+        return min;
+    }
+
+    private Number resolveMaxRange(Number max) {
+        int i = 1;
+        while (max instanceof UnknownBoundaryNumber) {
+            List<RangeConstraint> act = ranges.get(i);
+            max = act.get(act.size() - 1).getMax();
+            i++;
+        }
+        return max;
+    }
+
+    public void addRanges(List<RangeConstraint> ranges) {
+        if (ranges != null && ranges.size() > 0) {
+            this.ranges.add(ranges);
+        }
+    }
+
+    public List<List<LengthConstraint>> getAllLengths() {
+        return lengths;
+    }
+
+    public List<LengthConstraint> getLength() {
+        List<LengthConstraint> resolved = lengths.get(0);
+        LengthConstraint firstLength = resolved.get(0);
+        LengthConstraint lastLength = resolved.get(resolved.size() - 1);
+        Number min = firstLength.getMin();
+        Number max = lastLength.getMax();
+
+        if (!(min instanceof UnknownBoundaryNumber)
+                && !(max instanceof UnknownBoundaryNumber)) {
+            return resolved;
+        }
+
+        if (firstLength == lastLength) {
+            if (min instanceof UnknownBoundaryNumber) {
+                min = resolveMinLength(min);
+            }
+            if (max instanceof UnknownBoundaryNumber) {
+                max = resolveMaxLength(max);
+            }
+            firstLength = BaseConstraints.lengthConstraint(min, max,
+                    firstLength.getDescription(), firstLength.getReference());
+            resolved.set(0, firstLength);
+            lastLength = BaseConstraints.lengthConstraint(min, max,
+                    lastLength.getDescription(), lastLength.getReference());
+            resolved.set(resolved.size() - 1, lastLength);
+        } else {
+            if (min instanceof UnknownBoundaryNumber) {
+                min = resolveMinLength(min);
+                firstLength = BaseConstraints.lengthConstraint(min,
+                        firstLength.getMax(), firstLength.getDescription(),
+                        firstLength.getReference());
+                resolved.set(0, firstLength);
+            }
+            if (max instanceof UnknownBoundaryNumber) {
+                max = resolveMaxLength(max);
+                lastLength = BaseConstraints.lengthConstraint(
+                        lastLength.getMin(), max, lastLength.getDescription(),
+                        lastLength.getReference());
+                resolved.set(resolved.size() - 1, lastLength);
+            }
+        }
+        return resolved;
+    }
+
+    private Number resolveMinLength(Number min) {
+        int i = 1;
+        while (min instanceof UnknownBoundaryNumber) {
+            List<LengthConstraint> act = lengths.get(i);
+            min = act.get(0).getMin();
+            i++;
+        }
+        return min;
+    }
+
+    private Number resolveMaxLength(Number max) {
+        int i = 1;
+        while (max instanceof UnknownBoundaryNumber) {
+            List<LengthConstraint> act = lengths.get(i);
+            max = act.get(act.size() - 1).getMax();
+            i++;
+        }
+        return max;
+    }
+
+    public void addLengths(List<LengthConstraint> lengths) {
+        if (lengths != null && lengths.size() > 0) {
+            this.lengths.add(lengths);
+        }
+    }
+
+    public List<PatternConstraint> getPatterns() {
+        return patterns;
+    }
+
+    public void addPatterns(List<PatternConstraint> patterns) {
+        this.patterns.addAll(patterns);
+    }
+
+    public Integer getFractionDigits() {
+        return fractionDigits;
+    }
+
+    public void setFractionDigits(Integer fractionDigits) {
+        if (fractionDigits != null) {
+            this.fractionDigits = fractionDigits;
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/UnknownBoundaryNumber.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/UnknownBoundaryNumber.java
new file mode 100644 (file)
index 0000000..27127f0
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.model.parser.util;
+
+/**
+ * Marker object representing special 'min' or 'max' values in YANG.
+ */
+public final class UnknownBoundaryNumber extends Number {
+    private static final long serialVersionUID = 1464861684686434869L;
+
+    private final String value;
+
+    UnknownBoundaryNumber(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public int intValue() {
+        return 0;
+    }
+
+    @Override
+    public long longValue() {
+        return 0;
+    }
+
+    @Override
+    public float floatValue() {
+        return 0;
+    }
+
+    @Override
+    public double doubleValue() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return UnknownBoundaryNumber.class.getSimpleName() + "[" + value + "]";
+    }
+
+}
index 31ec765..b1ab253 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Stack;
 
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Argument_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bit_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bits_specificationContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_argContext;
@@ -49,6 +50,8 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.String_restrictio
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Units_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.When_stmtContext;
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yin_element_argContext;
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yin_element_stmtContext;
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
@@ -56,11 +59,11 @@ 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.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.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.BitsTypeDefinition.Bit;
 import org.opendaylight.controller.yang.model.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.controller.yang.model.parser.builder.impl.ConstraintsBuilder;
 import org.opendaylight.controller.yang.model.util.BaseConstraints;
@@ -76,7 +79,7 @@ import org.opendaylight.controller.yang.model.util.YangTypesConverter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class YangModelBuilderUtil {
+public final class YangModelBuilderUtil {
 
     private static final Logger logger = LoggerFactory
             .getLogger(YangModelBuilderUtil.class);
@@ -304,7 +307,6 @@ public class YangModelBuilderUtil {
         result.description = description;
         result.reference = reference;
         result.status = status;
-        // TODO: extensionSchemaNodes
         result.name = name;
         result.value = value;
         return result;
@@ -500,8 +502,8 @@ public class YangModelBuilderUtil {
         String[] splittedRange = trimmed.split("\\|");
         for (String rangeDef : splittedRange) {
             String[] splittedRangeDef = rangeDef.split("\\.\\.");
-            Long min;
-            Long max;
+            Number min;
+            Number max;
             if (splittedRangeDef.length == 1) {
                 min = max = parseRangeValue(splittedRangeDef[0]);
             } else {
@@ -554,8 +556,8 @@ public class YangModelBuilderUtil {
         String[] splittedRange = trimmed.split("\\|");
         for (String rangeDef : splittedRange) {
             String[] splittedRangeDef = rangeDef.split("\\.\\.");
-            Long min;
-            Long max;
+            Number min;
+            Number max;
             if (splittedRangeDef.length == 1) {
                 min = max = parseRangeValue(splittedRangeDef[0]);
             } else {
@@ -570,12 +572,10 @@ public class YangModelBuilderUtil {
         return lengthConstraints;
     }
 
-    private static Long parseRangeValue(String value) {
-        Long result = null;
-        if (value.equals("min")) {
-            result = Long.MIN_VALUE;
-        } else if (value.equals("max")) {
-            result = Long.MAX_VALUE;
+    private static Number parseRangeValue(String value) {
+        Number result = null;
+        if(value.equals("min") || value.equals("max")) {
+            result = new UnknownBoundaryNumber(value);
         } else {
             result = Long.valueOf(value);
         }
@@ -627,10 +627,15 @@ public class YangModelBuilderUtil {
                 reference);
     }
 
-    public static String patternStringFromNode(final Pattern_stmtContext treeNode) {
+    /**
+     * Parse given context and return pattern value.
+     * @param ctx context to parse
+     * @return pattern value as String
+     */
+    public static String patternStringFromNode(final Pattern_stmtContext ctx) {
         String result = "";
-        for (int i = 0; i < treeNode.getChildCount(); ++i) {
-            ParseTree child = treeNode.getChild(i);
+        for (int i = 0; i < ctx.getChildCount(); ++i) {
+            ParseTree child = ctx.getChild(i);
             if (child instanceof StringContext) {
                 for(int j = 0; j < child.getChildCount(); j++) {
                     if(j % 2 == 0) {
@@ -722,7 +727,7 @@ public class YangModelBuilderUtil {
                 String positionStr = stringFromNode(child);
                 position = Long.valueOf(positionStr);
                 if (position < 0 || position > 4294967295L) {
-                    throw new IllegalArgumentException(
+                    throw new YangParseException(
                             "position value MUST be in the range 0 to 4294967295, but was: "
                                     + position);
                 }
@@ -735,9 +740,10 @@ public class YangModelBuilderUtil {
             }
         }
 
-        // TODO: extensionDefinitions
+        final List<UnknownSchemaNode> extensionSchemaNodes = Collections
+                .emptyList();
         return createBit(qname, schemaPath, description, reference, status,
-                null, position);
+                extensionSchemaNodes, position);
     }
 
     private static BitsTypeDefinition.Bit createBit(final QName qname,
@@ -1010,7 +1016,8 @@ public class YangModelBuilderUtil {
                     absolute);
             type = new Leafref(xpath);
         } else if (typeName.equals("binary")) {
-            type = new BinaryType(null, lengthStatements, null);
+            List<Byte> bytes = Collections.emptyList();
+            type = new BinaryType(bytes, lengthStatements, null);
         } else if (typeName.equals("instance-identifier")) {
             boolean requireInstance = isRequireInstance(typeBody);
             type = new InstanceIdentifier(null, requireInstance);
@@ -1112,4 +1119,30 @@ public class YangModelBuilderUtil {
         }
     }
 
+    /**
+     * Parse given context and return yin value.
+     * @param ctx context to parse
+     * @return true if value is 'true', false otherwise
+     */
+    public static boolean parseYinValue(Argument_stmtContext ctx) {
+        boolean yinValue = false;
+        outer:
+        for(int j = 0; j < ctx.getChildCount(); j++) {
+            ParseTree yin = ctx.getChild(j);
+            if(yin instanceof Yin_element_stmtContext) {
+                for(int k = 0; k < yin.getChildCount(); k++) {
+                    ParseTree yinArg = yin.getChild(k);
+                    if(yinArg instanceof Yin_element_argContext) {
+                        String yinString = stringFromNode(yinArg);
+                        if(yinString.equals("true")) {
+                            yinValue = true;
+                            break outer;
+                        }
+                    }
+                }
+            }
+        }
+        return yinValue;
+    }
+
 }
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangParseException.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangParseException.java
new file mode 100644 (file)
index 0000000..bc1c9d6
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/eplv10.html
+ */
+package org.opendaylight.controller.yang.model.parser.util;
+
+public class YangParseException extends RuntimeException {
+
+    private static final long serialVersionUID = 1239548963471793178L;
+
+    public YangParseException(String errorMsg) {
+        super(errorMsg);
+    }
+
+}
index 0c8de22..1ecd67f 100644 (file)
@@ -120,8 +120,8 @@ public class TypesResolutionTest {
         List<LengthConstraint> lengths = baseType.getLengthStatements();
         assertEquals(1, lengths.size());
         LengthConstraint length = baseType.getLengthStatements().get(0);
-        assertEquals(1L, (long)length.getMin());
-        assertEquals(253L, (long)length.getMax());
+        assertEquals(1L, length.getMin());
+        assertEquals(253L, length.getMax());
     }
 
     @Test
index 9881080..e02d832 100644 (file)
@@ -21,9 +21,10 @@ import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
-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.util.Decimal64;
 import org.opendaylight.controller.yang.model.util.Int32;
@@ -99,9 +100,9 @@ public class YangModelParserTest {
         assertTrue(testleaf.getType().getBaseType() instanceof Int32);
         Int32 baseTypeCast = (Int32)baseType;
         List<RangeConstraint> ranges = baseTypeCast.getRangeStatements();
-        assertEquals(2, ranges.size());
+        assertEquals(1, ranges.size());
         RangeConstraint range = ranges.get(0);
-        assertEquals(2L, range.getMin());
+        assertEquals(11L, range.getMin());
         assertEquals(20L, range.getMax());
     }
 
@@ -150,22 +151,15 @@ public class YangModelParserTest {
         }
         assertNotNull(m1);
 
-        LeafSchemaNode testleaf = (LeafSchemaNode)m1.getDataChildByName("test-int-leaf");
+        LeafSchemaNode testleaf = (LeafSchemaNode)m1.getDataChildByName("leaf-with-length");
         TypeDefinition<?> baseType = testleaf.getType().getBaseType();
-        assertTrue(testleaf.getType().getBaseType() instanceof IntegerTypeDefinition);
-        Int32 baseTypeCast = (Int32)baseType;
-
-        Long[][] expectedRanges = new Long[3][2];
-        expectedRanges[0] = new Long[]{10L, 20L};
-        expectedRanges[1] = new Long[]{12L, 18L};
-        expectedRanges[2] = new Long[]{14L, 16L};
+        assertTrue(testleaf.getType().getBaseType() instanceof StringTypeDefinition);
+        StringType baseTypeCast = (StringType)baseType;
 
-        List<RangeConstraint> actualRanges = baseTypeCast.getRangeStatements();
-        assertEquals(3, actualRanges.size());
-        for(int i = 0; i < actualRanges.size(); i++) {
-            assertEquals(expectedRanges[i][0], actualRanges.get(i).getMin());
-            assertEquals(expectedRanges[i][1], actualRanges.get(i).getMax());
-        }
+        List<LengthConstraint> actualLengths = baseTypeCast.getLengthStatements();
+        assertEquals(1, actualLengths.size());
+        assertEquals(7L, actualLengths.get(0).getMin());
+        assertEquals(10L, actualLengths.get(0).getMax());
     }
 
     @Test
@@ -186,9 +180,9 @@ public class YangModelParserTest {
         assertTrue(testleaf.getType().getBaseType() instanceof Int32);
         Int32 baseTypeCast = (Int32)baseType;
         List<RangeConstraint> ranges = baseTypeCast.getRangeStatements();
-        assertEquals(2, ranges.size());
+        assertEquals(1, ranges.size());
         RangeConstraint range = ranges.get(0);
-        assertEquals(2L, range.getMin());
+        assertEquals(11L, range.getMin());
         assertEquals(20L, range.getMax());
     }
 
index 0d5fba7..9e779c2 100644 (file)
@@ -28,10 +28,10 @@ module types1 {
                  type int32;\r
              }\r
          }\r
-     }\r
+    }\r
      \r
     leaf testleaf {\r
-        type data:my-base-int32-type {\r
+        type data:my-type1 {\r
             range "min..max";\r
         }\r
     }\r
@@ -40,6 +40,12 @@ module types1 {
         type data:my-string-type-ext;\r
     }\r
     \r
+    leaf leaf-with-length {\r
+       type data:my-string-type {\r
+               length "7..max";\r
+       }\r
+    }\r
+    \r
     leaf test-int-leaf {\r
         type data:my-int-type-ext;\r
     }\r
@@ -53,5 +59,9 @@ module types1 {
     leaf test-decimal-leaf2 {\r
         type data:my-decimal-type-ext;\r
     }\r
+    \r
+    container ext {\r
+        data:c-define "MY_INTERFACES";\r
+    }\r
 \r
 }\r
index aea5fb4..ea12a50 100644 (file)
@@ -16,6 +16,18 @@ module types2 {
         reference " WILL BE DEFINED LATER";\r
     }\r
     \r
+    typedef ranges1 {\r
+       type int32 {\r
+               range "10..20";\r
+       }\r
+    }\r
+    \r
+    typedef ranges2 {\r
+       type ranges1 {\r
+               range "12..max";\r
+       }\r
+    }\r
+    \r
     typedef my-base-int32-type {\r
         type int32 {\r
             range "2..20";\r
@@ -29,8 +41,16 @@ module types2 {
     }\r
     \r
     typedef my-string-type {\r
-        type string {\r
+        type my-custom-string {\r
             pattern "[a-k]*";\r
+            length "5..10";\r
+        }\r
+    }\r
+    \r
+    typedef my-custom-string {\r
+       type string {\r
+            pattern "[a-k]*";\r
+            length "5..11";\r
         }\r
     }\r
     \r
@@ -96,5 +116,15 @@ module types2 {
     leaf nested-type-leaf {\r
         type my-type1;\r
     }\r
+    \r
+    extension c-define {\r
+        description\r
+        "Takes as argument a name string.\r
+        Makes the code generator use the given name in the\r
+        #define.";\r
+        argument "name" {\r
+            yin-element "true";\r
+        }\r
+    }\r
 \r
 }\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang1.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang1.yang
deleted file mode 100644 (file)
index 16d6087..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-module types1 {
-       yang-version 1;
-    namespace "urn:simple.container.demo";
-    prefix "t1";
-    
-
-    organization "Cisco";
-
-    contact "WILL-BE-DEFINED-LATER";
-    
-    
-    container interfaces {
-         list ifEntry {
-             key "ifIndex";
-
-             leaf ifIndex {
-                 type uint32;
-             }
-             leaf ifDescr {
-                 type string;
-             }
-             leaf ifType {
-                 type uint8;
-             }
-             leaf ifMtu {
-                 type int32;
-             }
-         }
-     }
-    
-    
-    
-    
-    
-//    leaf name {
-//             type my-string;
-//     }
-       
-//     typedef my-string {
-//             type string {
-//                     length "0..4";
-//             pattern "[0-9a-fA-F]*";
-//             }
-//     }
-
-
-//     leaf completed {
-//             type types2:percent;
-//  }
-
-//     leaf testleaf {
-//             type data:my-base-int32-type;
-//     }
-
-//     leaf-list domain-search {
-//             type string;
-//             description "List of domain names to search";
-//     }
-       
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang2.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang2.yang
deleted file mode 100644 (file)
index 8c73b51..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-module types2 {
-       yang-version 1;
-    namespace "urn:simple.types.data.demo";
-    prefix "t2";
-    
-    import types1 {
-         prefix "if";
-     }
-
-    organization "Cisco";
-
-    contact "WILL-BE-DEFINED-LATER";
-
-    description "This is types-data test description";
-
-    revision "2013-02-27" {
-        reference " WILL BE DEFINED LATER";
-    }
-    
-    
-     augment "/if:interfaces/if:ifEntry" {
-         when "if:ifType='ds0'";
-         leaf ds0ChannelNumber {
-             type string;
-         }
-     }
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang3.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/yang3.yang
deleted file mode 100644 (file)
index 0d09259..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-module types3 {
-       yang-version 1;
-    namespace "urn:simple.types3.data.demo";
-    prefix "scd";
-
-    organization "Cisco";
-
-    contact "WILL-BE-DEFINED-LATER";
-
-    description "This is types-data test description";
-
-    revision "2013-02-27" {
-        reference " WILL BE DEFINED LATER";
-    }
-    
-    typedef my-decimal {
-         type decimal64 {
-               fraction-digits 2;
-         }
-    }
-
-       typedef my-base-int32-type {
-         type int32 {
-               range "0..32";
-         }
-    }
-    
-    typedef percent {
-         type uint8 {
-             range "0 .. 100";
-         }
-         description "Percentage";
-       }
-       
-}
index 2db9e8a..3d259a5 100644 (file)
@@ -27,7 +27,7 @@ import org.opendaylight.controller.yang.model.api.ConstraintMetaDefinition;
  * This interface was modeled according to definition in <a
  * href="https://tools.ietf.org/html/rfc6020#section-9.4.4">[RFC-6020] The
  * length Statement</a>.
- * 
+ *
  * @see ConstraintMetaDefinition
  */
 public interface LengthConstraint extends ConstraintMetaDefinition {
@@ -35,16 +35,16 @@ public interface LengthConstraint extends ConstraintMetaDefinition {
     /**
      * Returns the length-restricting lower bound value. <br>
      * The value MUST NOT be negative.
-     * 
+     *
      * @return the length-restricting lower bound value.
      */
-    Long getMin();
+    Number getMin();
 
     /**
      * Returns the length-restricting upper bound value. <br>
      * The value MUST NOT be negative.
-     * 
+     *
      * @return length-restricting upper bound value.
      */
-    Long getMax();
+    Number getMax();
 }
index dfc4d55..23a2d5f 100644 (file)
@@ -16,8 +16,8 @@ public final class BaseConstraints {
     private BaseConstraints() {
     }
 
-    public static LengthConstraint lengthConstraint(final long min,
-            final long max, final String description, final String reference) {
+    public static LengthConstraint lengthConstraint(final Number min,
+            final Number max, final String description, final String reference) {
         return new LengthConstraintImpl(min, max, description, reference);
     }
 
@@ -33,8 +33,8 @@ public final class BaseConstraints {
 
     private static final class LengthConstraintImpl implements LengthConstraint {
 
-        private final long min;
-        private final long max;
+        private final Number min;
+        private final Number max;
 
         private final String description;
         private final String reference;
@@ -42,7 +42,7 @@ public final class BaseConstraints {
         private final String errorAppTag;
         private final String errorMessage;
 
-        public LengthConstraintImpl(long min, long max,
+        public LengthConstraintImpl(Number min, Number max,
                 final String description, final String reference) {
             super();
             this.min = min;
@@ -76,12 +76,12 @@ public final class BaseConstraints {
         }
 
         @Override
-        public Long getMin() {
+        public Number getMin() {
             return min;
         }
 
         @Override
-        public Long getMax() {
+        public Number getMax() {
             return max;
         }
 
@@ -95,8 +95,8 @@ public final class BaseConstraints {
                     + ((errorAppTag == null) ? 0 : errorAppTag.hashCode());
             result = prime * result
                     + ((errorMessage == null) ? 0 : errorMessage.hashCode());
-            result = prime * result + (int) (max ^ (max >>> 32));
-            result = prime * result + (int) (min ^ (min >>> 32));
+            result = prime * result + ((max == null) ? 0 : max.hashCode());
+            result = prime * result + ((min == null) ? 0 : min.hashCode());
             result = prime * result
                     + ((reference == null) ? 0 : reference.hashCode());
             return result;
index b564088..c676d74 100644 (file)
@@ -44,13 +44,13 @@ public class StringType implements StringTypeDefinition {
         final List<LengthConstraint> constraints = new ArrayList<LengthConstraint>();
         constraints.add(BaseConstraints.lengthConstraint(0, Long.MAX_VALUE, "", ""));
         lengthStatements = Collections.unmodifiableList(constraints);
-        
+
         this.patterns = Collections.emptyList();
     }
 
     /**
-     * 
-     * 
+     *
+     *
      * @param lengthStatements
      * @param patterns
      */
@@ -58,13 +58,19 @@ public class StringType implements StringTypeDefinition {
             final List<PatternConstraint> patterns) {
         super();
         path = BaseTypes.schemaPath(name);
-        this.lengthStatements = Collections.unmodifiableList(lengthStatements);
+        if(lengthStatements == null || lengthStatements.size() == 0) {
+            final List<LengthConstraint> constraints = new ArrayList<LengthConstraint>();
+            constraints.add(BaseConstraints.lengthConstraint(0, Long.MAX_VALUE, "", ""));
+            this.lengthStatements = Collections.unmodifiableList(constraints);
+        } else {
+            this.lengthStatements = Collections.unmodifiableList(lengthStatements);
+        }
         this.patterns = Collections.unmodifiableList(patterns);
     }
 
     /**
-     * 
-     * 
+     *
+     *
      * @param defaultValue
      * @param lengthStatements
      * @param patterns
@@ -76,14 +82,20 @@ public class StringType implements StringTypeDefinition {
         super();
         path = BaseTypes.schemaPath(name);
         this.defaultValue = defaultValue;
-        this.lengthStatements = lengthStatements;
+        if(lengthStatements == null || lengthStatements.size() == 0) {
+            final List<LengthConstraint> constraints = new ArrayList<LengthConstraint>();
+            constraints.add(BaseConstraints.lengthConstraint(0, Long.MAX_VALUE, "", ""));
+            this.lengthStatements = Collections.unmodifiableList(constraints);
+        } else {
+            this.lengthStatements = Collections.unmodifiableList(lengthStatements);
+        }
         this.patterns = patterns;
         this.units = units;
     }
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getBaseType()
      */
     @Override
@@ -93,7 +105,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getUnits()
      */
     @Override
@@ -103,7 +115,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.TypeDefinition#getDefaultValue()
      */
     @Override
@@ -113,7 +125,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.SchemaNode#getQName()
      */
     @Override
@@ -123,7 +135,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.SchemaNode#getPath()
      */
     @Override
@@ -133,7 +145,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.SchemaNode#getDescription()
      */
     @Override
@@ -143,7 +155,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.SchemaNode#getReference()
      */
     @Override
@@ -153,7 +165,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see org.opendaylight.controller.yang.model.api.SchemaNode#getStatus()
      */
     @Override
@@ -163,7 +175,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see
      * com.csico.yang.model.base.type.api.StringTypeDefinition#getLengthStatements
      * ()
@@ -175,7 +187,7 @@ public class StringType implements StringTypeDefinition {
 
     /*
      * (non-Javadoc)
-     * 
+     *
      * @see
      * com.csico.yang.model.base.type.api.StringTypeDefinition#getPatterns()
      */