YANGTOOLS-621: introduce specialized integer types
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / SchemaContextEmitter.java
index 9a37e3ecfd46c775bac38fb6871d80255fd97955..3a28f320c7926025619587d65732c02dd6eb2a2f 100644 (file)
@@ -10,12 +10,12 @@ package org.opendaylight.yangtools.yang.model.export;
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicates;
-import com.google.common.base.Strings;
 import com.google.common.collect.Collections2;
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
 import com.google.common.primitives.UnsignedInteger;
 import java.net.URI;
 import java.util.Collection;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -27,11 +27,12 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.NotThreadSafe;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.YangVersion;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
@@ -199,17 +200,16 @@ abstract class SchemaContextEmitter {
              * augment) we can get declared form i.e. ModuleStatement and then
              * use DeclaredSchemaContextEmitter
              */
-            new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions,
-                    YangVersion.parse(module.getYangVersion()).orElse(null))
-                            .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
+            new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion())
+            .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
         } else {
             /*
              * if we don't have access to declared form of supplied module or we
              * want to emit also instantiated statements (e.g. statements added
              * by uses or augment), we use EffectiveSchemaContextEmitter.
              */
-            new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions,
-                    YangVersion.parse(module.getYangVersion()).orElse(null), emitInstantiated).emitModule(module);
+            new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion(), emitInstantiated)
+            .emitModule(module);
         }
     }
 
@@ -1116,7 +1116,7 @@ abstract class SchemaContextEmitter {
                 } else if (child instanceof ConfigStatement) {
                     emitConfigNode((ConfigStatement) child);
                 } else if (child instanceof UnknownStatement) {
-                    emitUnknownStatementNode((UnknownStatement<?>) child);
+                    emitUnknownStatementNode(child);
                 }
             }
             super.writer.endNode();
@@ -1168,10 +1168,9 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitMetaNodes(final Module input) {
-            emitOrganizationNode(input.getOrganization());
-            emitContact(input.getContact());
-            emitDescriptionNode(input.getDescription());
-            emitReferenceNode(input.getReference());
+            input.getOrganization().ifPresent(this::emitOrganizationNode);
+            input.getContact().ifPresent(this::emitContact);
+            emitDocumentedNode(input);
         }
 
         private void emitLinkageNodes(final Module input) {
@@ -1188,8 +1187,7 @@ abstract class SchemaContextEmitter {
              * FIXME: BUG-2444: emit revisions properly, when parsed model will
              * provide enough information
              */
-            emitRevision(input.getRevision());
-
+            input.getRevision().ifPresent(this::emitRevision);
         }
 
         private void emitBodyNodes(final Module input) {
@@ -1209,7 +1207,7 @@ abstract class SchemaContextEmitter {
 
             emitDataNodeContainer(input);
 
-            for (final AugmentationSchema augmentation : input.getAugmentations()) {
+            for (final AugmentationSchemaNode augmentation : input.getAugmentations()) {
                 emitAugment(augmentation);
             }
             for (final RpcDefinition rpc : input.getRpcs()) {
@@ -1259,17 +1257,16 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitYangVersionNode(final String input) {
-            super.writer.startYangVersionNode(input);
+        private void emitYangVersionNode(final YangVersion input) {
+            super.writer.startYangVersionNode(input.toString());
             super.writer.endNode();
         }
 
         private void emitImport(final ModuleImport importNode) {
             super.writer.startImportNode(importNode.getModuleName());
-            emitDescriptionNode(importNode.getDescription());
-            emitReferenceNode(importNode.getReference());
+            emitDocumentedNode(importNode);
             emitPrefixNode(importNode.getPrefix());
-            emitRevisionDateNode(importNode.getRevision());
+            importNode.getRevision().ifPresent(this::emitRevisionDateNode);
             super.writer.endNode();
         }
 
@@ -1314,65 +1311,51 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitOrganizationNode(final String input) {
-            if (!Strings.isNullOrEmpty(input)) {
-                super.writer.startOrganizationNode(input);
-                super.writer.endNode();
-            }
+            super.writer.startOrganizationNode(input);
+            super.writer.endNode();
         }
 
         private void emitContact(final String input) {
-            if (!Strings.isNullOrEmpty(input)) {
-                super.writer.startContactNode(input);
-                super.writer.endNode();
-            }
+            super.writer.startContactNode(input);
+            super.writer.endNode();
         }
 
-        private void emitDescriptionNode(@Nullable final String input) {
-            if (!Strings.isNullOrEmpty(input)) {
-                super.writer.startDescriptionNode(input);
-                super.writer.endNode();
-            }
+        private void emitDescriptionNode(final String input) {
+            super.writer.startDescriptionNode(input);
+            super.writer.endNode();
         }
 
-        private void emitReferenceNode(@Nullable final String input) {
-            if (!Strings.isNullOrEmpty(input)) {
-                super.writer.startReferenceNode(input);
-                super.writer.endNode();
-            }
+        private void emitReferenceNode(final String input) {
+            super.writer.startReferenceNode(input);
+            super.writer.endNode();
         }
 
         private void emitUnitsNode(@Nullable final String input) {
-            if (!Strings.isNullOrEmpty(input)) {
-                super.writer.startUnitsNode(input);
-                super.writer.endNode();
-            }
-        }
-
-        private void emitRevision(final Date date) {
-            super.writer.startRevisionNode(date);
-
-            //
-            // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode
-            // //FIXME: BUG-2444: Optional
-            // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode
-            // //FIXME: BUG-2444: Optional
+            super.writer.startUnitsNode(input);
             super.writer.endNode();
-
         }
 
-        private void emitRevisionDateNode(@Nullable final Date date) {
+        private void emitRevision(final Revision date) {
             if (date != null) {
-                super.writer.startRevisionDateNode(date);
+                super.writer.startRevisionNode(date);
+
+                // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode
+                // //FIXME: BUG-2444: Optional
+                // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode
+                // //FIXME: BUG-2444: Optional
                 super.writer.endNode();
             }
         }
 
+        private void emitRevisionDateNode(final Revision date) {
+            super.writer.startRevisionDateNode(date);
+            super.writer.endNode();
+        }
+
         private void emitExtension(final ExtensionDefinition extension) {
             super.writer.startExtensionNode(extension.getQName());
             emitArgument(extension.getArgument(), extension.isYinElement());
-            emitStatusNode(extension.getStatus());
-            emitDescriptionNode(extension.getDescription());
-            emitReferenceNode(extension.getReference());
+            emitDocumentedNode(extension);
             emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
             super.writer.endNode();
 
@@ -1396,9 +1379,7 @@ abstract class SchemaContextEmitter {
         private void emitIdentity(final IdentitySchemaNode identity) {
             super.writer.startIdentityNode(identity.getQName());
             emitBaseIdentities(identity.getBaseIdentities());
-            emitStatusNode(identity.getStatus());
-            emitDescriptionNode(identity.getDescription());
-            emitReferenceNode(identity.getReference());
+            emitDocumentedNode(identity);
             super.writer.endNode();
         }
 
@@ -1418,11 +1399,8 @@ abstract class SchemaContextEmitter {
 
             // FIXME: BUG-2444: FIXME: BUG-2444: Expose ifFeature
             // *(ifFeatureNode )
-            emitStatusNode(definition.getStatus());
-            emitDescriptionNode(definition.getDescription());
-            emitReferenceNode(definition.getReference());
+            emitDocumentedNode(definition);
             super.writer.endNode();
-
         }
 
         @SuppressWarnings("unused")
@@ -1439,14 +1417,11 @@ abstract class SchemaContextEmitter {
             // Differentiate between derived type and existing type
             // name.
             emitTypeNodeDerived(typedef);
-            emitUnitsNode(typedef.getUnits());
-            emitDefaultNode(typedef.getDefaultValue());
-            emitStatusNode(typedef.getStatus());
-            emitDescriptionNode(typedef.getDescription());
-            emitReferenceNode(typedef.getReference());
+            typedef.getUnits().ifPresent(this::emitUnitsNode);
+            typedef.getDefaultValue().ifPresent(this::emitDefaultNode);
+            emitDocumentedNode(typedef);
             emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
             super.writer.endNode();
-
         }
 
         private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
@@ -1475,9 +1450,9 @@ abstract class SchemaContextEmitter {
 
         private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
             if (typeDef instanceof UnsignedIntegerTypeDefinition) {
-                emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
+                emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition<?, ?>) typeDef);
             } else if (typeDef instanceof IntegerTypeDefinition) {
-                emitIntegerSpefication((IntegerTypeDefinition) typeDef);
+                emitIntegerSpefication((IntegerTypeDefinition<?, ?>) typeDef);
             } else if (typeDef instanceof DecimalTypeDefinition) {
                 emitDecimal64Specification((DecimalTypeDefinition) typeDef);
             } else if (typeDef instanceof StringTypeDefinition) {
@@ -1495,7 +1470,7 @@ abstract class SchemaContextEmitter {
             } else if (typeDef instanceof UnionTypeDefinition) {
                 emitUnionSpecification((UnionTypeDefinition) typeDef);
             } else if (typeDef instanceof BinaryTypeDefinition) {
-                emitLength(((BinaryTypeDefinition) typeDef).getLengthConstraints());
+                ((BinaryTypeDefinition) typeDef).getLengthConstraint().ifPresent(this::emitLength);
             } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
                 // NOOP
             } else {
@@ -1503,35 +1478,25 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
-            emitRangeNodeOptional(typeDef.getRangeConstraints());
+        private void emitIntegerSpefication(final IntegerTypeDefinition<?, ?> typeDef) {
+            typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
         }
 
-        private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
-            emitRangeNodeOptional(typeDef.getRangeConstraints());
-
+        private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition<?, ?> typeDef) {
+            typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
         }
 
-        private void emitRangeNodeOptional(final List<RangeConstraint> list) {
-            // FIXME: BUG-2444: Wrong decomposition in API, should be
-            // LenghtConstraint
-            // which contains ranges.
-            if (!list.isEmpty()) {
-                super.writer.startRangeNode(toRangeString(list));
-                final RangeConstraint first = list.iterator().next();
-                emitErrorMessageNode(first.getErrorMessage());
-                emitErrorAppTagNode(first.getErrorAppTag());
-                emitDescriptionNode(first.getDescription());
-                emitReferenceNode(first.getReference());
-                super.writer.endNode();
-            }
-
+        private void emitRangeNode(final RangeConstraint<?> constraint) {
+            super.writer.startRangeNode(toRangeString(constraint.getAllowedRanges()));
+            constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
+            constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
+            emitDocumentedNode(constraint);
+            super.writer.endNode();
         }
 
         private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
             emitFranctionDigitsNode(typeDefinition.getFractionDigits());
-            emitRangeNodeOptional(typeDefinition.getRangeConstraints());
-
+            typeDefinition.getRangeConstraint().ifPresent(this::emitRangeNode);
         }
 
         private void emitFranctionDigitsNode(final Integer fractionDigits) {
@@ -1540,34 +1505,23 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitStringRestrictions(final StringTypeDefinition typeDef) {
-
-            // FIXME: BUG-2444: Wrong decomposition in API, should be
-            // LenghtConstraint
-            // which contains ranges.
-            emitLength(typeDef.getLengthConstraints());
+            typeDef.getLengthConstraint().ifPresent(this::emitLength);
 
             for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
                 emitPatternNode(pattern);
             }
-
         }
 
-        private void emitLength(final List<LengthConstraint> list) {
-            if (!list.isEmpty()) {
-                super.writer.startLengthNode(toLengthString(list));
-                // FIXME: BUG-2444: Workaround for incorrect decomposition in
-                // API
-                final LengthConstraint first = list.iterator().next();
-                emitErrorMessageNode(first.getErrorMessage());
-                emitErrorAppTagNode(first.getErrorAppTag());
-                emitDescriptionNode(first.getDescription());
-                emitReferenceNode(first.getReference());
-                super.writer.endNode();
-            }
+        private void emitLength(final LengthConstraint constraint) {
+            super.writer.startLengthNode(toLengthString(constraint.getAllowedRanges()));
+            constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
+            constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
+            emitDocumentedNode(constraint);
+            super.writer.endNode();
         }
 
-        private static String toLengthString(final List<LengthConstraint> list) {
-            final Iterator<LengthConstraint> it = list.iterator();
+        private static String toLengthString(final RangeSet<Integer> ranges) {
+            final Iterator<Range<Integer>> it = ranges.asRanges().iterator();
             if (!it.hasNext()) {
                 return "";
             }
@@ -1575,16 +1529,16 @@ abstract class SchemaContextEmitter {
             final StringBuilder sb = new StringBuilder();
             boolean haveNext;
             do {
-                final LengthConstraint current = it.next();
+                final Range<Integer> current = it.next();
                 haveNext = it.hasNext();
-                appendRange(sb, current.getMin(), current.getMax(), haveNext);
+                appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
             } while (haveNext);
 
             return sb.toString();
         }
 
-        private static String toRangeString(final List<RangeConstraint> list) {
-            final Iterator<RangeConstraint> it = list.iterator();
+        private static String toRangeString(final RangeSet<?> ranges) {
+            final Iterator<? extends Range<?>> it = ranges.asRanges().iterator();
             if (!it.hasNext()) {
                 return "";
             }
@@ -1592,15 +1546,15 @@ abstract class SchemaContextEmitter {
             final StringBuilder sb = new StringBuilder();
             boolean haveNext;
             do {
-                final RangeConstraint current = it.next();
+                final Range<?> current = it.next();
                 haveNext = it.hasNext();
-                appendRange(sb, current.getMin(), current.getMax(), haveNext);
+                appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
             } while (haveNext);
 
             return sb.toString();
         }
 
-        private static void appendRange(final StringBuilder sb, final Number min, final Number max,
+        private static void appendRange(final StringBuilder sb, final Object min, final Object max,
                 final boolean haveNext) {
             sb.append(min);
             if (!min.equals(max)) {
@@ -1613,21 +1567,17 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitPatternNode(final PatternConstraint pattern) {
-            super.writer.startPatternNode(pattern.getRawRegularExpression());
-            // FIXME: BUG-2444: Optional
-            emitErrorMessageNode(pattern.getErrorMessage());
-            // FIXME: BUG-2444: Optional
-            emitErrorAppTagNode(pattern.getErrorAppTag());
-            emitDescriptionNode(pattern.getDescription());
-            emitModifier(pattern.getModifier());
+            super.writer.startPatternNode(pattern.getRegularExpressionString());
+            pattern.getErrorMessage().ifPresent(this::emitErrorMessageNode);
+            pattern.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
+            emitDocumentedNode(pattern);
+            pattern.getModifier().ifPresent(this::emitModifier);
             super.writer.endNode();
         }
 
         private void emitModifier(final ModifierKind modifier) {
-            if (modifier != null) {
-                super.writer.startModifierNode(modifier);
-                super.writer.endNode();
-            }
+            super.writer.startModifierNode(modifier);
+            super.writer.endNode();
         }
 
         private void emitDefaultNodes(final Collection<String> defaults) {
@@ -1637,10 +1587,8 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitDefaultNode(@Nullable final Object object) {
-            if (object != null) {
-                super.writer.startDefaultNode(object.toString());
-                super.writer.endNode();
-            }
+            super.writer.startDefaultNode(object.toString());
+            super.writer.endNode();
         }
 
         private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
@@ -1652,9 +1600,7 @@ abstract class SchemaContextEmitter {
         private void emitEnumNode(final EnumPair enumValue) {
             super.writer.startEnumNode(enumValue.getName());
             emitValueNode(enumValue.getValue());
-            emitStatusNode(enumValue.getStatus());
-            emitDescriptionNode(enumValue.getDescription());
-            emitReferenceNode(enumValue.getReference());
+            emitDocumentedNode(enumValue);
             super.writer.endNode();
         }
 
@@ -1700,9 +1646,7 @@ abstract class SchemaContextEmitter {
         private void emitBit(final Bit bit) {
             super.writer.startBitNode(bit.getName());
             emitPositionNode(bit.getPosition());
-            emitStatusNode(bit.getStatus());
-            emitDescriptionNode(bit.getDescription());
-            emitReferenceNode(bit.getReference());
+            emitDocumentedNode(bit);
             super.writer.endNode();
         }
 
@@ -1747,27 +1691,21 @@ abstract class SchemaContextEmitter {
         private void emitMust(@Nullable final MustDefinition mustCondition) {
             if (mustCondition != null && mustCondition.getXpath() != null) {
                 super.writer.startMustNode(mustCondition.getXpath());
-                emitErrorMessageNode(mustCondition.getErrorMessage());
-                emitErrorAppTagNode(mustCondition.getErrorAppTag());
-                emitDescriptionNode(mustCondition.getDescription());
-                emitReferenceNode(mustCondition.getReference());
+                mustCondition.getErrorMessage().ifPresent(this::emitErrorMessageNode);
+                mustCondition.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
+                emitDocumentedNode(mustCondition);
                 super.writer.endNode();
             }
-
         }
 
         private void emitErrorMessageNode(@Nullable final String input) {
-            if (input != null && !input.isEmpty()) {
-                super.writer.startErrorMessageNode(input);
-                super.writer.endNode();
-            }
+            super.writer.startErrorMessageNode(input);
+            super.writer.endNode();
         }
 
         private void emitErrorAppTagNode(final String input) {
-            if (input != null && !input.isEmpty()) {
-                super.writer.startErrorAppTagNode(input);
-                super.writer.endNode();
-            }
+            super.writer.startErrorAppTagNode(input);
+            super.writer.endNode();
         }
 
         private void emitMinElementsNode(final Integer min) {
@@ -1791,10 +1729,14 @@ abstract class SchemaContextEmitter {
             }
         }
 
+        private void emitDocumentedNode(final DocumentedNode input) {
+            input.getDescription().ifPresent(this::emitDescriptionNode);
+            input.getReference().ifPresent(this::emitReferenceNode);
+        }
+
         private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
             emitStatusNode(input.getStatus());
-            emitDescriptionNode(input.getDescription());
-            emitReferenceNode(input.getReference());
+            emitDocumentedNode((DocumentedNode) input);
         }
 
         private void emitGrouping(final GroupingDefinition grouping) {
@@ -1810,9 +1752,6 @@ abstract class SchemaContextEmitter {
 
         private void emitContainer(final ContainerSchemaNode child) {
             super.writer.startContainerNode(child.getQName());
-
-            //
-
             emitConstraints(child.getConstraints());
             // FIXME: BUG-2444: whenNode //:Optional
             // FIXME: BUG-2444: *(ifFeatureNode )
@@ -1828,7 +1767,7 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitConstraints(final ConstraintDefinition constraints) {
-            emitWhen(constraints.getWhenCondition());
+            constraints.getWhenCondition().ifPresent(this::emitWhen);
             for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
                 emitMust(mustCondition);
             }
@@ -1836,12 +1775,12 @@ abstract class SchemaContextEmitter {
 
         private void emitLeaf(final LeafSchemaNode child) {
             super.writer.startLeafNode(child.getQName());
-            emitWhen(child.getConstraints().getWhenCondition());
+            child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitTypeNode(child.getPath(), child.getType());
-            emitUnitsNode(child.getUnits());
+            child.getType().getUnits().ifPresent(this::emitUnitsNode);
             emitMustNodes(child.getConstraints().getMustConstraints());
-            emitDefaultNode(child.getDefault());
+            child.getType().getDefaultValue().ifPresent(this::emitDefaultNode);
             emitConfigNode(child.isConfiguration());
             emitMandatoryNode(child.getConstraints().isMandatory());
             emitDocumentedNode(child);
@@ -1853,10 +1792,10 @@ abstract class SchemaContextEmitter {
         private void emitLeafList(final LeafListSchemaNode child) {
             super.writer.startLeafListNode(child.getQName());
 
-            emitWhen(child.getConstraints().getWhenCondition());
+            child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitTypeNode(child.getPath(), child.getType());
-            emitUnitsNode(child.getType().getUnits());
+            child.getType().getUnits().ifPresent(this::emitUnitsNode);
             // FIXME: BUG-2444: unitsNode /Optional
             emitMustNodes(child.getConstraints().getMustConstraints());
             emitConfigNode(child.isConfiguration());
@@ -1872,7 +1811,7 @@ abstract class SchemaContextEmitter {
 
         private void emitList(final ListSchemaNode child) {
             super.writer.startListNode(child.getQName());
-            emitWhen(child.getConstraints().getWhenCondition());
+            child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
 
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitMustNodes(child.getConstraints().getMustConstraints());
@@ -1891,7 +1830,7 @@ abstract class SchemaContextEmitter {
 
         }
 
-        private void emitMustNodes(final Set<MustDefinition> mustConstraints) {
+        private void emitMustNodes(final Collection<MustDefinition> mustConstraints) {
             for (final MustDefinition must : mustConstraints) {
                 emitMust(must);
             }
@@ -1917,13 +1856,13 @@ abstract class SchemaContextEmitter {
 
         private void emitChoice(final ChoiceSchemaNode choice) {
             super.writer.startChoiceNode(choice.getQName());
-            emitWhen(choice.getConstraints().getWhenCondition());
+            choice.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             // FIXME: BUG-2444: defaultNode //Optional
             emitConfigNode(choice.isConfiguration());
             emitMandatoryNode(choice.getConstraints().isMandatory());
             emitDocumentedNode(choice);
-            for (final ChoiceCaseNode caze : choice.getCases()) {
+            for (final ChoiceCaseNode caze : choice.getCases().values()) {
                 // TODO: emit short case?
                 emitCaseNode(caze);
             }
@@ -1936,7 +1875,7 @@ abstract class SchemaContextEmitter {
                 return;
             }
             super.writer.startCaseNode(caze.getQName());
-            emitWhen(caze.getConstraints().getWhenCondition());
+            caze.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitDocumentedNode(caze);
             emitDataNodeContainer(caze);
@@ -1958,7 +1897,7 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
-            emitWhen(dataSchemaNode.getConstraints().getWhenCondition());
+            dataSchemaNode.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
             emitConfigNode(dataSchemaNode.isConfiguration());
@@ -1978,7 +1917,7 @@ abstract class SchemaContextEmitter {
                 for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
                     emitRefine(refine);
                 }
-                for (final AugmentationSchema aug : usesNode.getAugmentations()) {
+                for (final AugmentationSchemaNode aug : usesNode.getAugmentations()) {
                     emitUsesAugmentNode(aug);
                 }
                 super.writer.endNode();
@@ -2019,10 +1958,10 @@ abstract class SchemaContextEmitter {
 
         private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
             if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
-                emitDescriptionNode(value.getDescription());
+                value.getDescription().ifPresent(this::emitDescriptionNode);
             }
             if (Objects.deepEquals(original.getReference(), value.getReference())) {
-                emitReferenceNode(value.getReference());
+                value.getReference().ifPresent(this::emitReferenceNode);
             }
         }
 
@@ -2044,8 +1983,8 @@ abstract class SchemaContextEmitter {
             final LeafSchemaNode original = getOriginalChecked(value);
 
             // emitMustNodes(child.getConstraints().getMustConstraints());
-            if (Objects.deepEquals(original.getDefault(), value.getDefault())) {
-                emitDefaultNode(value.getDefault());
+            if (Objects.deepEquals(original.getType().getDefaultValue(), value.getType().getDefaultValue())) {
+                emitDefaultNode(value.getType().getDefaultValue());
             }
             if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
                 emitConfigNode(value.isConfiguration());
@@ -2130,7 +2069,7 @@ abstract class SchemaContextEmitter {
 
         }
 
-        private void emitUsesAugmentNode(final AugmentationSchema aug) {
+        private void emitUsesAugmentNode(final AugmentationSchemaNode aug) {
             /**
              * differs only in location in schema, otherwise currently (as of
              * RFC6020) it is same, so we could freely reuse path.
@@ -2138,14 +2077,12 @@ abstract class SchemaContextEmitter {
             emitAugment(aug);
         }
 
-        private void emitAugment(final AugmentationSchema augmentation) {
+        private void emitAugment(final AugmentationSchemaNode augmentation) {
             super.writer.startAugmentNode(augmentation.getTargetPath());
             // FIXME: BUG-2444: whenNode //Optional
             // FIXME: BUG-2444: *(ifFeatureNode )
 
-            emitStatusNode(augmentation.getStatus());
-            emitDescriptionNode(augmentation.getDescription());
-            emitReferenceNode(augmentation.getReference());
+            emitDocumentedNode(augmentation);
             for (final UsesNode uses : augmentation.getUses()) {
                 emitUsesNode(uses);
             }
@@ -2207,9 +2144,7 @@ abstract class SchemaContextEmitter {
 
         private void emitOperationBody(final OperationDefinition rpc) {
             // FIXME: BUG-2444: *(ifFeatureNode )
-            emitStatusNode(rpc.getStatus());
-            emitDescriptionNode(rpc.getDescription());
-            emitReferenceNode(rpc.getReference());
+            emitDocumentedNode(rpc);
 
             for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
                 emitTypedefNode(typedef);
@@ -2229,8 +2164,10 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitAction(final ActionDefinition action) {
-            // :FIXME add addedByUses & addedByAugmentation in API and perform
-            // check here..
+            if (!super.emitInstantiated && (action.isAddedByUses() || action.isAugmenting())) {
+                // We skip instantiated nodes.
+                return;
+            }
             super.writer.startActionNode(action.getQName());
             emitOperationBody(action);
             super.writer.endNode();
@@ -2269,12 +2206,16 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitNotificationNode(final NotificationDefinition notification) {
-            // :FIXME add addedByUses & addedByAugmentation in API and perform
-            // check here..
+            if (!super.emitInstantiated && (notification.isAddedByUses() || notification.isAugmenting())) {
+                // We skip instantiated nodes.
+                return;
+            }
 
             super.writer.startNotificationNode(notification.getQName());
             // FIXME: BUG-2444: *(ifFeatureNode )
-            emitConstraints(notification.getConstraints());
+            for (final MustDefinition mustCondition : notification.getMustConstraints()) {
+                emitMust(mustCondition);
+            }
             emitDocumentedNode(notification);
             emitDataNodeContainer(notification);
             emitUnknownStatementNodes(notification.getUnknownSchemaNodes());