Merge changes I296b2805,Iee01f474,I13dab228
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / ModuleBuilder.java
index 020d7594bf95d9ce0c912d3f64c48146e1961483..5c4afe6ae17b49e99535784d7e4ab2a74c28f26a 100644 (file)
@@ -6,20 +6,26 @@
  */
 package org.opendaylight.yangtools.yang.parser.builder.impl;
 
+import com.google.common.base.Preconditions;
+import com.google.common.io.ByteSource;
+import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Deque;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
-
+import org.apache.commons.io.IOUtils;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
@@ -45,13 +51,10 @@ import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.UnknownSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDocumentedDataNodeContainer;
 import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDocumentedDataNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.util.Comparators;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
-import com.google.common.collect.ImmutableSet;
-
 /**
  * Builder of Module object. If this module is dependent on external
  * module/modules, these dependencies must be resolved before module is built,
@@ -63,19 +66,22 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     private final String name;
     private final String sourcePath;
     private static final SchemaPath SCHEMA_PATH = SchemaPath.create(Collections.<QName> emptyList(), true);
-    private URI namespace;
     private String prefix;
-    private Date revision;
+    private QNameModule qnameModule = QNameModule.create(null, null);
 
     private final boolean submodule;
     private String belongsTo;
     private ModuleBuilder parent;
 
-
     private final Deque<Builder> actualPath = new LinkedList<>();
     private final Set<TypeAwareBuilder> dirtyNodes = new HashSet<>();
 
-    private final Set<ModuleImport> imports = new HashSet<ModuleImport>();
+    final Map<String, ModuleImport> imports = new HashMap<>();
+    final Map<String, ModuleBuilder> importedModules = new HashMap<>();
+
+    final Set<ModuleBuilder> addedSubmodules = new HashSet<>();
+    final Set<Module> submodules = new HashSet<>();
+    final Map<String, Date> includedModules = new HashMap<>();
 
     private final Set<AugmentationSchema> augments = new LinkedHashSet<>();
     private final List<AugmentationSchemaBuilder> augmentBuilders = new ArrayList<>();
@@ -116,31 +122,25 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         this(name, false, sourcePath);
     }
 
-    @Override
-    protected String getStatementName() {
-        return "module";
-    }
-
     public ModuleBuilder(final String name, final boolean submodule, final String sourcePath) {
         super(name, 0, null);
         this.name = name;
         this.sourcePath = sourcePath;
         this.submodule = submodule;
-        actualPath.push(this);
+        actualPath.push(this);//FIXME: this escapes constructor
     }
 
     public ModuleBuilder(final Module base) {
-        super(base.getName(), 0, new QName(base.getNamespace(), base.getRevision(), base.getPrefix(), base.getName()),
+        super(base.getName(), 0, QName.create(base.getQNameModule(), base.getPrefix(), base.getName()),
                 SCHEMA_PATH, base);
         this.name = base.getName();
         this.sourcePath = base.getModuleSourcePath();
 
         submodule = false;
         yangVersion = base.getYangVersion();
-        actualPath.push(this);
-        namespace = base.getNamespace();
+        actualPath.push(this);//FIXME: this escapes constructor
         prefix = base.getPrefix();
-        revision = base.getRevision();
+        qnameModule = base.getQNameModule();
 
         augments.addAll(base.getAugmentations());
         rpcs.addAll(base.getRpcs());
@@ -154,6 +154,12 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         deviations.addAll(base.getDeviations());
         extensions.addAll(base.getExtensionSchemaNodes());
         unknownNodes.addAll(base.getUnknownSchemaNodes());
+        source = base.getSource();
+    }
+
+    @Override
+    protected String getStatementName() {
+        return "module";
     }
 
     /**
@@ -161,60 +167,61 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
      */
     @Override
     public Module build() {
+        if(instance != null) {
+            return instance;
+        }
+
         buildChildren();
-        instance = new ModuleImpl(name, sourcePath, this);
+
+        // SUBMODULES
+        for (ModuleBuilder submodule : addedSubmodules) {
+            submodules.add(submodule.build());
+        }
+
         // FEATURES
         for (FeatureBuilder fb : addedFeatures) {
             features.add(fb.build());
         }
-        instance.setFeatures(features);
 
         // NOTIFICATIONS
         for (NotificationBuilder entry : addedNotifications) {
             notifications.add(entry.build());
         }
-        instance.setNotifications(notifications);
 
         // AUGMENTATIONS
         for (AugmentationSchemaBuilder builder : augmentBuilders) {
             augments.add(builder.build());
         }
-        instance.setAugmentations(augments);
 
         // RPCs
         for (RpcDefinitionBuilder rpc : addedRpcs) {
             rpcs.add(rpc.build());
         }
-        instance.setRpcs(rpcs);
 
         // DEVIATIONS
         for (DeviationBuilder entry : deviationBuilders) {
             deviations.add(entry.build());
         }
-        instance.setDeviations(deviations);
 
         // EXTENSIONS
         for (ExtensionBuilder eb : addedExtensions) {
             extensions.add(eb.build());
         }
         Collections.sort(extensions, Comparators.SCHEMA_NODE_COMP);
-        instance.setExtensionSchemaNodes(extensions);
+
 
         // IDENTITIES
         for (IdentitySchemaNodeBuilder id : addedIdentities) {
             identities.add(id.build());
         }
-        instance.setIdentities(identities);
 
         // UNKNOWN NODES
         for (UnknownSchemaNodeBuilder unb : addedUnknownNodes) {
             unknownNodes.add(unb.build());
         }
         Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
-        instance.setUnknownSchemaNodes(unknownNodes);
-
-        instance.setSource(source);
 
+        instance = new ModuleImpl(name, sourcePath, this);
         return instance;
     }
 
@@ -326,11 +333,19 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public URI getNamespace() {
-        return namespace;
+        return qnameModule.getNamespace();
+    }
+
+    public QNameModule getQNameModule() {
+        return qnameModule;
+    }
+
+    public void setQNameModule(final QNameModule qnameModule) {
+        this.qnameModule = Preconditions.checkNotNull(qnameModule);
     }
 
     public void setNamespace(final URI namespace) {
-        this.namespace = namespace;
+        this.qnameModule = QNameModule.create(namespace, qnameModule.getRevision());
     }
 
     public String getPrefix() {
@@ -338,7 +353,40 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public Date getRevision() {
-        return revision;
+        return qnameModule.getRevision();
+    }
+
+    public ModuleImport getImport(final String prefix) {
+        return imports.get(prefix);
+    }
+
+    public Map<String, ModuleImport> getImports() {
+        return imports;
+    }
+
+    public ModuleBuilder getImportedModule(final String prefix) {
+        return importedModules.get(prefix);
+    }
+
+    public void addImportedModule(final String prefix, final ModuleBuilder module) {
+        checkPrefix(prefix);
+        importedModules.put(prefix, module);
+    }
+
+    public Map<String, Date> getIncludedModules() {
+        return includedModules;
+    }
+
+    public void addInclude(final String name, final Date revision) {
+        includedModules.put(name, revision);
+    }
+
+    public void addSubmodule(final ModuleBuilder submodule) {
+        addedSubmodules.add(submodule);
+    }
+
+    protected String getSource() {
+        return source;
     }
 
     public boolean isSubmodule() {
@@ -359,7 +407,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public void setRevision(final Date revision) {
-        this.revision = revision;
+        this.qnameModule = QNameModule.create(qnameModule.getNamespace(), revision);
     }
 
     public void setPrefix(final String prefix) {
@@ -378,16 +426,24 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         this.contact = contact;
     }
 
-    public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) {
+    public void addModuleImport(final String moduleName, final Date revision, final String prefix) {
+        checkPrefix(prefix);
+        checkNotSealed();
         final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix);
-        return imports.add(moduleImport);
+        imports.put(prefix, moduleImport);
     }
 
-    public Set<ModuleImport> getModuleImports() {
-        return imports;
+    private void checkPrefix(final String prefix) {
+        if (prefix == null || prefix.isEmpty()) {
+            throw new IllegalArgumentException("Cannot add imported module with undefined prefix");
+        }
+        if (prefix.equals(this.prefix)) {
+            throw new IllegalArgumentException("Cannot add imported module with prefix equals to module prefix");
+        }
     }
 
     public ExtensionBuilder addExtension(final QName qname, final int line, final SchemaPath path) {
+        checkNotSealed();
         Builder parent = getActualNode();
         if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "extension can be defined only in module or submodule");
@@ -406,6 +462,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        checkNotSealed();
         final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
@@ -416,6 +473,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public ListSchemaNodeBuilder addListNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        checkNotSealed();
         final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
@@ -427,6 +485,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public LeafSchemaNodeBuilder addLeafNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        checkNotSealed();
         final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
@@ -437,6 +496,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        checkNotSealed();
         final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
@@ -447,6 +507,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public GroupingBuilder addGrouping(final int line, final QName qname, final SchemaPath path) {
+        checkNotSealed();
         final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname, path);
 
         Builder parent = getActualNode();
@@ -486,8 +547,11 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         return builder;
     }
 
-    public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr, final int order) {
-        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr, order);
+    public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr,
+            final SchemaPath targetPath, final int order) {
+        checkNotSealed();
+        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr,
+                targetPath, order);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
@@ -519,8 +583,9 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         return builder;
     }
 
-    public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) {
-        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, groupingPathStr);
+    public UsesNodeBuilder addUsesNode(final int line, final SchemaPath grouping) {
+        checkNotSealed();
+        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, grouping);
 
         Builder parent = getActualNode();
         usesBuilder.setParent(parent);
@@ -529,7 +594,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
             addUsesNode(usesBuilder);
         } else {
             if (!(parent instanceof DataNodeContainerBuilder)) {
-                throw new YangParseException(name, line, "Unresolved parent of uses '" + groupingPathStr + "'.");
+                throw new YangParseException(name, line, "Unresolved parent of uses '" + grouping + "'.");
             }
             ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder);
         }
@@ -542,6 +607,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public void addRefine(final RefineHolderImpl refine) {
+        checkNotSealed();
         final Builder parent = getActualNode();
         if (!(parent instanceof UsesNodeBuilder)) {
             throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
@@ -551,6 +617,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public RpcDefinitionBuilder addRpc(final int line, final QName qname, final SchemaPath path) {
+        checkNotSealed();
         Builder parent = getActualNode();
         if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "rpc can be defined only in module or submodule");
@@ -584,6 +651,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) {
+        checkNotSealed();
         final Builder parent = getActualNode();
         if (!(parent instanceof RpcDefinitionBuilder)) {
             throw new YangParseException(name, line, "input can be defined only in rpc statement");
@@ -598,6 +666,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) {
+        checkNotSealed();
         final Builder parent = getActualNode();
         if (!(parent instanceof RpcDefinitionBuilder)) {
             throw new YangParseException(name, line, "output can be defined only in rpc statement");
@@ -612,10 +681,12 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public void addNotification(final NotificationDefinition notification) {
+        checkNotSealed();
         notifications.add(notification);
     }
 
     public NotificationBuilder addNotification(final int line, final QName qname, final SchemaPath path) {
+        checkNotSealed();
         final Builder parent = getActualNode();
         if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "notification can be defined only in module or submodule");
@@ -690,9 +761,6 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         return builder;
     }
 
-
-
-
     @Override
     public void addTypedef(final TypeDefinitionBuilder typedefBuilder) {
         String nodeName = typedefBuilder.getQName().getLocalName();
@@ -747,7 +815,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         ((TypeAwareBuilder) parent).setType(type);
     }
 
-    public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) {
+    public UnionTypeBuilder addUnionType(final int line, final QNameModule module) {
         final Builder parent = getActualNode();
         if (parent == null) {
             throw new YangParseException(name, line, "Unresolved parent of union type");
@@ -779,7 +847,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         }
     }
 
-    public DeviationBuilder addDeviation(final int line, final String targetPath) {
+    public DeviationBuilder addDeviation(final int line, final SchemaPath targetPath) {
         Builder parent = getActualNode();
         if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
@@ -825,11 +893,11 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
             addedUnknownNodes.add(builder);
         } else {
             if (parent instanceof SchemaNodeBuilder) {
-                ((SchemaNodeBuilder) parent).addUnknownNodeBuilder(builder);
+                parent.addUnknownNodeBuilder(builder);
             } else if (parent instanceof DataNodeContainerBuilder) {
-                ((DataNodeContainerBuilder) parent).addUnknownNodeBuilder(builder);
+                parent.addUnknownNodeBuilder(builder);
             } else if (parent instanceof RefineHolderImpl) {
-                ((RefineHolderImpl) parent).addUnknownNodeBuilder(builder);
+                parent.addUnknownNodeBuilder(builder);
             } else {
                 throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName()
                         + "'");
@@ -860,251 +928,14 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         return "module " + name;
     }
 
-    public void setSource(final String source) {
-        this.source = source;
-    }
-
-    public static final class ModuleImpl extends AbstractDocumentedDataNodeContainer implements Module {
-        private final URI namespace;
-        private final String name;
-        private final String sourcePath;
-        private final Date revision;
-        private final String prefix;
-        private final String yangVersion;
-        private final String organization;
-        private final String contact;
-        private final Set<ModuleImport> imports;
-        private final Set<FeatureDefinition> features = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
-        private final Set<NotificationDefinition> notifications = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
-        private final Set<AugmentationSchema> augmentations = new HashSet<>();
-        private final Set<RpcDefinition> rpcs = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
-        private final Set<Deviation> deviations = new HashSet<>();
-        private final List<ExtensionDefinition> extensionNodes = new ArrayList<>();
-        private final Set<IdentitySchemaNode> identities = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
-        private final List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
-        private String source;
-
-        private ModuleImpl(final String name, final String sourcePath, final ModuleBuilder builder) {
-            super(builder);
-            this.name = name;
-            this.sourcePath = sourcePath;
-            this.imports = ImmutableSet.<ModuleImport>copyOf(builder.imports);
-            this.namespace = builder.getNamespace();
-            this.prefix = builder.getPrefix();
-            this.revision = builder.getRevision();
-            this.yangVersion = builder.getYangVersion();
-            this.organization = builder.getOrganization();
-            this.contact = builder.getContact();
-        }
-
-        @Override
-        public String getModuleSourcePath() {
-            return sourcePath;
-        }
-
-        @Override
-        public URI getNamespace() {
-            return namespace;
-        }
-
-        @Override
-        public String getName() {
-            return name;
-        }
-
-        @Override
-        public Date getRevision() {
-            return revision;
-        }
-
-        @Override
-        public String getPrefix() {
-            return prefix;
-        }
-
-        @Override
-        public String getYangVersion() {
-            return yangVersion;
-        }
-
-        @Override
-        public String getOrganization() {
-            return organization;
-        }
-
-        @Override
-        public String getContact() {
-            return contact;
-        }
-
-        @Override
-        public Set<ModuleImport> getImports() {
-            return imports;
-        }
-
-        @Override
-        public Set<FeatureDefinition> getFeatures() {
-            return features;
-        }
-
-        private void setFeatures(final Set<FeatureDefinition> features) {
-            if (features != null) {
-                this.features.addAll(features);
-            }
-        }
-
-        @Override
-        public Set<NotificationDefinition> getNotifications() {
-            return notifications;
-        }
-
-        private void setNotifications(final Set<NotificationDefinition> notifications) {
-            if (notifications != null) {
-                this.notifications.addAll(notifications);
-            }
-        }
-
-        @Override
-        public Set<AugmentationSchema> getAugmentations() {
-            return augmentations;
-        }
-
-        private void setAugmentations(final Set<AugmentationSchema> augmentations) {
-            if (augmentations != null) {
-                this.augmentations.addAll(augmentations);
-            }
-        }
-
-        @Override
-        public Set<RpcDefinition> getRpcs() {
-            return rpcs;
-        }
-
-        private void setRpcs(final Set<RpcDefinition> rpcs) {
-            if (rpcs != null) {
-                this.rpcs.addAll(rpcs);
-            }
-        }
-
-        @Override
-        public Set<Deviation> getDeviations() {
-            return deviations;
-        }
-
-        private void setDeviations(final Set<Deviation> deviations) {
-            if (deviations != null) {
-                this.deviations.addAll(deviations);
-            }
-        }
-
-        @Override
-        public List<ExtensionDefinition> getExtensionSchemaNodes() {
-            Collections.sort(extensionNodes, Comparators.SCHEMA_NODE_COMP);
-            return extensionNodes;
-        }
-
-        private void setExtensionSchemaNodes(final List<ExtensionDefinition> extensionNodes) {
-            if (extensionNodes != null) {
-                this.extensionNodes.addAll(extensionNodes);
-            }
-        }
-
-        @Override
-        public Set<IdentitySchemaNode> getIdentities() {
-            return identities;
-        }
-
-        private void setIdentities(final Set<IdentitySchemaNode> identities) {
-            if (identities != null) {
-                this.identities.addAll(identities);
-            }
-        }
-
-        @Override
-        public List<UnknownSchemaNode> getUnknownSchemaNodes() {
-            return unknownNodes;
-        }
-
-        private void setUnknownSchemaNodes(final List<UnknownSchemaNode> unknownNodes) {
-            if (unknownNodes != null) {
-                this.unknownNodes.addAll(unknownNodes);
-            }
-        }
-
-        void setSource(final String source) {
-            this.source = source;
-        }
-
-        public String getSource() {
-            return source;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
-            result = prime * result + ((name == null) ? 0 : name.hashCode());
-            result = prime * result + ((revision == null) ? 0 : revision.hashCode());
-            result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            ModuleImpl other = (ModuleImpl) obj;
-            if (namespace == null) {
-                if (other.namespace != null) {
-                    return false;
-                }
-            } else if (!namespace.equals(other.namespace)) {
-                return false;
-            }
-            if (name == null) {
-                if (other.name != null) {
-                    return false;
-                }
-            } else if (!name.equals(other.name)) {
-                return false;
-            }
-            if (revision == null) {
-                if (other.revision != null) {
-                    return false;
-                }
-            } else if (!revision.equals(other.revision)) {
-                return false;
-            }
-            if (yangVersion == null) {
-                if (other.yangVersion != null) {
-                    return false;
-                }
-            } else if (!yangVersion.equals(other.yangVersion)) {
-                return false;
-            }
-            return true;
+    public void setSource(final ByteSource byteSource) throws IOException {
+        try (InputStream stream = byteSource.openStream()) {
+            setSource(IOUtils.toString(stream));
         }
+    }
 
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName());
-            sb.append("[");
-            sb.append("name=" + name);
-            sb.append(", namespace=" + namespace);
-            sb.append(", revision=" + revision);
-            sb.append(", prefix=" + prefix);
-            sb.append(", yangVersion=" + yangVersion);
-            sb.append("]");
-            return sb.toString();
-        }
+    public void setSource(final String source) {
+        this.source = source;
     }
 
     /**
@@ -1220,8 +1051,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) {
-        final ModuleImport moduleImport = new ModuleImportImpl(moduleName, revision, prefix);
-        return moduleImport;
+        return new ModuleImportImpl(moduleName, revision, prefix);
     }
 
     private void raiseYangParserException(final String cantAddType, final String type, final String name,
@@ -1244,8 +1074,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         final int prime = 31;
         int result = 1;
         result = prime * result + ((name == null) ? 0 : name.hashCode());
-        result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
-        result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+        result = prime * result + qnameModule.hashCode();
         result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
 
         return result;
@@ -1270,11 +1099,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         } else if (!name.equals(other.name)) {
             return false;
         }
-        if (namespace == null) {
-            if (other.namespace != null) {
-                return false;
-            }
-        } else if (!namespace.equals(other.namespace)) {
+        if (!qnameModule.equals(other.qnameModule)) {
             return false;
         }
         if (prefix == null) {
@@ -1284,13 +1109,10 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         } else if (!prefix.equals(other.prefix)) {
             return false;
         }
-        if (revision == null) {
-            if (other.revision != null) {
-                return false;
-            }
-        } else if (!revision.equals(other.revision)) {
-            return false;
-        }
         return true;
     }
+
+    public List<UnknownSchemaNode> getExtensionInstances() {
+        return unknownNodes;
+    }
 }