2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.model.export;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkState;
12 import static java.util.Objects.requireNonNull;
14 import com.google.common.annotations.Beta;
15 import com.google.common.collect.Range;
16 import com.google.common.collect.RangeSet;
17 import com.google.common.primitives.UnsignedInteger;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.List;
23 import java.util.Map.Entry;
24 import java.util.Objects;
25 import java.util.Optional;
27 import javax.annotation.concurrent.NotThreadSafe;
28 import org.eclipse.jdt.annotation.NonNull;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.common.Revision;
32 import org.opendaylight.yangtools.yang.common.YangVersion;
33 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
34 import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
41 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.Deviation;
43 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
44 import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
45 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
46 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
47 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
48 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
50 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
51 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
52 import org.opendaylight.yangtools.yang.model.api.Module;
53 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
54 import org.opendaylight.yangtools.yang.model.api.MustConstraintAware;
55 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
56 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
57 import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
58 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
59 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
60 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
61 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
62 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
63 import org.opendaylight.yangtools.yang.model.api.Status;
64 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
65 import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
66 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
67 import org.opendaylight.yangtools.yang.model.api.UsesNode;
68 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
69 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
70 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
71 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
72 import org.opendaylight.yangtools.yang.model.api.stmt.ActionStatement;
73 import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement;
74 import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement;
75 import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
76 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
77 import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement;
78 import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
79 import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement;
80 import org.opendaylight.yangtools.yang.model.api.stmt.BodyGroup;
81 import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
82 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
83 import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
84 import org.opendaylight.yangtools.yang.model.api.stmt.ContactStatement;
85 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
86 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionContainer;
87 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement;
88 import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
89 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
90 import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
91 import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
92 import org.opendaylight.yangtools.yang.model.api.stmt.DocumentationGroup;
93 import org.opendaylight.yangtools.yang.model.api.stmt.DocumentedConstraintGroup;
94 import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement;
95 import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement;
96 import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
97 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement;
98 import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement;
99 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
100 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
101 import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
102 import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
103 import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
104 import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
105 import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
106 import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
107 import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
108 import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
109 import org.opendaylight.yangtools.yang.model.api.stmt.LinkageGroup;
110 import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
111 import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
112 import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsStatement;
113 import org.opendaylight.yangtools.yang.model.api.stmt.MetaGroup;
114 import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
115 import org.opendaylight.yangtools.yang.model.api.stmt.ModifierStatement;
116 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
117 import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement;
118 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
119 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
120 import org.opendaylight.yangtools.yang.model.api.stmt.OperationGroup;
121 import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
122 import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationStatement;
123 import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
124 import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement;
125 import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement;
126 import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement;
127 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
128 import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
129 import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
130 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
131 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
132 import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement;
133 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement;
134 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionGroup;
135 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
136 import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
137 import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
138 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
139 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
140 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
141 import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
142 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement;
143 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
144 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
145 import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement;
146 import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
147 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
148 import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
149 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
150 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
151 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
152 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
153 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
154 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
155 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
156 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
157 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
158 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
159 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
160 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
161 import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
162 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
163 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
164 import org.opendaylight.yangtools.yang.model.api.type.RangeRestrictedTypeDefinition;
165 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
166 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
167 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
172 abstract class SchemaContextEmitter {
174 final YangModuleWriter writer;
175 final boolean emitInstantiated;
176 final boolean emitUses;
177 final Map<QName, StatementDefinition> extensions;
178 final YangVersion yangVersion;
180 SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
181 final YangVersion yangVersion) {
182 this(writer, extensions, yangVersion, false, true);
185 SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
186 final YangVersion yangVersion, final boolean emitInstantiated, final boolean emitUses) {
187 this.writer = requireNonNull(writer);
188 this.emitInstantiated = emitInstantiated;
189 this.emitUses = emitUses;
190 this.extensions = requireNonNull(extensions);
191 this.yangVersion = yangVersion;
194 static void writeToStatementWriter(final Module module, final SchemaContext ctx,
195 final StatementTextWriter statementWriter, final boolean emitInstantiated) {
196 final YangModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
197 final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
198 if (module instanceof EffectiveStatement && !emitInstantiated) {
200 * if module is an effective statement and we don't want to export
201 * instantiated statements (e.g. statements added by uses or
202 * augment) we can get declared form i.e. ModuleStatement and then
203 * use DeclaredSchemaContextEmitter
205 new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion())
206 .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
209 * if we don't have access to declared form of supplied module or we
210 * want to emit also instantiated statements (e.g. statements added
211 * by uses or augment), we use EffectiveSchemaContextEmitter.
213 new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion(), emitInstantiated)
218 // FIXME: Probably should be moved to utils bundle.
219 static <T> boolean isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
220 final Iterator<T> prefixIt = prefix.iterator();
221 final Iterator<T> otherIt = other.iterator();
222 while (prefixIt.hasNext()) {
223 if (!otherIt.hasNext()) {
226 if (!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
233 static class DeclaredSchemaContextEmitter extends SchemaContextEmitter {
235 DeclaredSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
236 final YangVersion yangVersion) {
237 super(writer, extensions, yangVersion);
240 void emitModule(final DeclaredStatement<?> declaredRootStmt) {
241 if (declaredRootStmt instanceof ModuleStatement) {
242 emitModule((ModuleStatement) declaredRootStmt);
243 } else if (declaredRootStmt instanceof SubmoduleStatement) {
244 emitSubmodule((SubmoduleStatement) declaredRootStmt);
246 throw new UnsupportedOperationException(
247 String.format("Yin export: unsupported declared statement %s", declaredRootStmt));
251 private void emitModule(final ModuleStatement module) {
252 super.writer.startModuleNode(module.rawArgument());
253 emitModuleHeader(module);
254 emitLinkageNodes(module);
255 emitMetaNodes(module);
256 emitRevisionNodes(module);
257 emitBodyNodes(module);
258 emitUnknownStatementNodes(module);
259 super.writer.endNode();
262 private void emitModuleHeader(final ModuleStatement input) {
263 emitYangVersionNode(input.getYangVersion());
264 emitNamespace(input.getNamespace());
265 emitPrefixNode(input.getPrefix());
268 private void emitSubmodule(final SubmoduleStatement submodule) {
269 super.writer.startSubmoduleNode(submodule.rawArgument());
270 emitSubmoduleHeaderNodes(submodule);
271 emitLinkageNodes(submodule);
272 emitMetaNodes(submodule);
273 emitRevisionNodes(submodule);
274 emitBodyNodes(submodule);
275 emitUnknownStatementNodes(submodule);
276 super.writer.endNode();
279 private void emitSubmoduleHeaderNodes(final SubmoduleStatement input) {
280 emitYangVersionNode(input.getYangVersion());
281 emitBelongsTo(input.getBelongsTo());
284 private void emitBelongsTo(final BelongsToStatement belongsTo) {
285 super.writer.startBelongsToNode(belongsTo.rawArgument());
286 emitPrefixNode(belongsTo.getPrefix());
287 super.writer.endNode();
290 private void emitMetaNodes(final MetaGroup input) {
291 emitOrganizationNode(input.getOrganization());
292 emitContact(input.getContact());
293 emitDescriptionNode(input.getDescription());
294 emitReferenceNode(input.getReference());
297 private void emitLinkageNodes(final LinkageGroup input) {
298 for (final ImportStatement importNode : input.getImports()) {
299 emitImport(importNode);
301 for (final IncludeStatement importNode : input.getIncludes()) {
302 emitInclude(importNode);
306 private void emitRevisionNodes(final RevisionGroup input) {
307 emitRevisions(input.getRevisions());
310 private void emitBodyNodes(final BodyGroup input) {
312 for (final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension : input
314 emitExtension(extension);
316 for (final FeatureStatement definition : input.getFeatures()) {
317 emitFeature(definition);
319 for (final IdentityStatement identity : input.getIdentities()) {
320 emitIdentity(identity);
322 for (final DeviationStatement deviation : input.getDeviations()) {
323 emitDeviation(deviation);
326 emitDataNodeContainer(input);
328 for (final AugmentStatement augmentation : input.getAugments()) {
329 emitAugment(augmentation);
331 for (final RpcStatement rpc : input.getRpcs()) {
335 emitNotifications(input.getNotifications());
338 private void emitDataNodeContainer(final DataDefinitionContainer input) {
339 for (final DataDefinitionStatement child : input.getDataDefinitions()) {
340 emitDataSchemaNode(child);
344 private void emitDataNodeContainer(final DataDefinitionContainer.WithReusableDefinitions input) {
345 for (final TypedefStatement typedef : input.getTypedefs()) {
346 emitTypedefNode(typedef);
348 for (final GroupingStatement grouping : input.getGroupings()) {
349 emitGrouping(grouping);
351 for (final DataDefinitionStatement child : input.getDataDefinitions()) {
352 emitDataSchemaNode(child);
356 private void emitDataSchemaNode(final DataDefinitionStatement child) {
357 if (child instanceof ContainerStatement) {
358 emitContainer((ContainerStatement) child);
359 } else if (child instanceof LeafStatement) {
360 emitLeaf((LeafStatement) child);
361 } else if (child instanceof LeafListStatement) {
362 emitLeafList((LeafListStatement) child);
363 } else if (child instanceof ListStatement) {
364 emitList((ListStatement) child);
365 } else if (child instanceof ChoiceStatement) {
366 emitChoice((ChoiceStatement) child);
367 } else if (child instanceof AnyxmlStatement) {
368 emitAnyxml((AnyxmlStatement) child);
369 } else if (child instanceof AnydataStatement) {
370 emitAnydata((AnydataStatement) child);
371 } else if (child instanceof UsesStatement) {
372 emitUsesNode((UsesStatement) child);
374 throw new UnsupportedOperationException("Not supported DataStatement type " + child.getClass());
378 private void emitYangVersionNode(final @Nullable YangVersionStatement yangVersionStatement) {
379 if (yangVersionStatement != null) {
380 super.writer.startYangVersionNode(yangVersionStatement.rawArgument());
381 super.writer.endNode();
385 private void emitImport(final ImportStatement importNode) {
386 super.writer.startImportNode(importNode.rawArgument());
387 emitDocumentedNode(importNode);
388 emitPrefixNode(importNode.getPrefix());
389 emitRevisionDateNode(importNode.getRevisionDate());
390 super.writer.endNode();
393 private void emitInclude(final IncludeStatement include) {
394 super.writer.startIncludeNode(include.rawArgument());
395 emitDocumentedNode(include);
396 emitRevisionDateNode(include.getRevisionDate());
397 super.writer.endNode();
400 private void emitNamespace(final NamespaceStatement namespaceStatement) {
401 super.writer.startNamespaceNode(requireNonNull(namespaceStatement, "Namespace must not be null").getUri());
402 super.writer.endNode();
405 private void emitPrefixNode(final PrefixStatement prefixStatement) {
406 super.writer.startPrefixNode(requireNonNull(prefixStatement, "Prefix must not be null").rawArgument());
407 super.writer.endNode();
410 private void emitOrganizationNode(final @Nullable OrganizationStatement organizationStatement) {
411 if (organizationStatement != null) {
412 super.writer.startOrganizationNode(organizationStatement.rawArgument());
413 super.writer.endNode();
417 private void emitContact(final @Nullable ContactStatement contactStatement) {
418 if (contactStatement != null) {
419 super.writer.startContactNode(contactStatement.rawArgument());
420 super.writer.endNode();
424 private void emitDescriptionNode(final @Nullable DescriptionStatement descriptionStatement) {
425 if (descriptionStatement != null) {
426 super.writer.startDescriptionNode(descriptionStatement.rawArgument());
427 super.writer.endNode();
431 private void emitReferenceNode(final @Nullable ReferenceStatement referenceStatement) {
432 if (referenceStatement != null) {
433 super.writer.startReferenceNode(referenceStatement.rawArgument());
434 super.writer.endNode();
438 private void emitUnitsNode(final @Nullable UnitsStatement unitsStatement) {
439 if (unitsStatement != null) {
440 super.writer.startUnitsNode(unitsStatement.rawArgument());
441 super.writer.endNode();
445 private void emitRevisions(final Collection<? extends RevisionStatement> revisions) {
446 for (final RevisionStatement revisionStatement : revisions) {
447 emitRevision(revisionStatement);
451 private void emitRevision(final RevisionStatement revision) {
452 super.writer.startRevisionNode(revision.rawArgument());
453 emitDocumentedNode(revision);
454 super.writer.endNode();
457 private void emitRevisionDateNode(final @Nullable RevisionDateStatement revisionDateStatement) {
458 if (revisionDateStatement != null) {
459 super.writer.startRevisionDateNode(revisionDateStatement.rawArgument());
460 super.writer.endNode();
464 private void emitExtension(final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension) {
465 super.writer.startExtensionNode(extension.rawArgument());
466 emitArgument(extension.getArgument());
467 emitDocumentedNodeWithStatus(extension);
468 emitUnknownStatementNodes(extension);
469 super.writer.endNode();
472 private void emitArgument(final @Nullable ArgumentStatement input) {
474 super.writer.startArgumentNode(input.rawArgument());
475 emitYinElement(input.getYinElement());
476 super.writer.endNode();
480 private void emitYinElement(final @Nullable YinElementStatement yinElementStatement) {
481 if (yinElementStatement != null) {
482 super.writer.startYinElementNode(yinElementStatement.rawArgument());
483 super.writer.endNode();
487 private void emitIdentity(final IdentityStatement identity) {
488 super.writer.startIdentityNode(identity.rawArgument());
489 emitBaseIdentities(identity.getBases());
490 emitStatusNode(identity.getStatus());
491 emitDescriptionNode(identity.getDescription());
492 emitReferenceNode(identity.getReference());
493 super.writer.endNode();
496 private void emitBaseIdentities(final Collection<? extends BaseStatement> collection) {
497 for (final BaseStatement baseStmt : collection) {
502 private void emitBase(final BaseStatement baseStmt) {
503 super.writer.startBaseNode(baseStmt.rawArgument());
504 super.writer.endNode();
507 private void emitFeature(final FeatureStatement feature) {
508 super.writer.startFeatureNode(feature.rawArgument());
509 emitIfFeatures(feature.getIfFeatures());
510 emitDocumentedNodeWithStatus(feature);
511 super.writer.endNode();
514 private void emitIfFeatures(final Collection<? extends IfFeatureStatement> ifFeatures) {
515 for (final IfFeatureStatement ifFeatureStatement : ifFeatures) {
516 emitIfFeature(ifFeatureStatement);
520 private void emitIfFeature(final IfFeatureStatement ifFeature) {
521 super.writer.startIfFeatureNode(ifFeature.rawArgument());
522 super.writer.endNode();
525 private void emitTypedefNode(final TypedefStatement typedef) {
526 super.writer.startTypedefNode(typedef.rawArgument());
527 emitType(typedef.getType());
528 emitUnitsNode(typedef.getUnits());
529 emitDefaultNode(typedef.getDefault());
530 emitStatusNode(typedef.getStatus());
531 emitDescriptionNode(typedef.getDescription());
532 emitReferenceNode(typedef.getReference());
533 emitUnknownStatementNodes(typedef);
534 super.writer.endNode();
537 private void emitType(final TypeStatement typeStatement) {
538 super.writer.startTypeNode(typeStatement.rawArgument());
539 for (final DeclaredStatement<?> typeSubstmt : typeStatement.declaredSubstatements()) {
540 if (typeSubstmt instanceof RangeStatement) {
541 emitRange((RangeStatement) typeSubstmt);
542 } else if (typeSubstmt instanceof LengthStatement) {
543 emitLength((LengthStatement) typeSubstmt);
544 } else if (typeSubstmt instanceof PatternStatement) {
545 emitPattern((PatternStatement) typeSubstmt);
546 } else if (typeSubstmt instanceof FractionDigitsStatement) {
547 emitFractionDigits((FractionDigitsStatement) typeSubstmt);
548 } else if (typeSubstmt instanceof EnumStatement) {
549 emitEnum((EnumStatement) typeSubstmt);
550 } else if (typeSubstmt instanceof PathStatement) {
551 emitPath((PathStatement) typeSubstmt);
552 } else if (typeSubstmt instanceof RequireInstanceStatement) {
553 emitRequireInstance((RequireInstanceStatement) typeSubstmt);
554 } else if (typeSubstmt instanceof BaseStatement) {
555 emitBase((BaseStatement) typeSubstmt);
556 } else if (typeSubstmt instanceof BitStatement) {
557 emitBit((BitStatement) typeSubstmt);
558 } else if (typeSubstmt instanceof TypeStatement) {
559 emitType((TypeStatement) typeSubstmt);
562 super.writer.endNode();
565 private void emitRange(final RangeStatement range) {
566 super.writer.startRangeNode(range.rawArgument());
567 emitDocumentedConstraint(range);
568 super.writer.endNode();
571 private void emitFractionDigits(final FractionDigitsStatement fractionDigits) {
572 super.writer.startFractionDigitsNode(fractionDigits.rawArgument());
573 super.writer.endNode();
576 private void emitLength(final LengthStatement lengthStatement) {
577 super.writer.startLengthNode(lengthStatement.rawArgument());
578 emitDocumentedConstraint(lengthStatement);
579 super.writer.endNode();
582 private void emitPattern(final PatternStatement pattern) {
583 super.writer.startPatternNode(pattern.rawArgument());
584 emitModifier(pattern.getModifierStatement());
585 emitDocumentedConstraint(pattern);
586 super.writer.endNode();
589 private void emitModifier(final ModifierStatement modifierStatement) {
590 if (modifierStatement != null) {
591 super.writer.startModifierNode(modifierStatement.rawArgument());
592 super.writer.endNode();
596 private void emitDefaultNodes(final Collection<? extends DefaultStatement> collection) {
597 for (final DefaultStatement defaultValue : collection) {
598 emitDefaultNode(defaultValue);
602 private void emitDefaultNode(final @Nullable DefaultStatement defaultStmt) {
603 if (defaultStmt != null) {
604 super.writer.startDefaultNode(defaultStmt.rawArgument());
605 super.writer.endNode();
609 private void emitEnum(final EnumStatement enumStmt) {
610 super.writer.startEnumNode(enumStmt.rawArgument());
611 emitDocumentedNodeWithStatus(enumStmt);
612 emitValueNode(enumStmt.getValue());
613 super.writer.endNode();
616 private void emitPath(final PathStatement path) {
617 super.writer.startPathNode(path.rawArgument());
618 super.writer.endNode();
621 private void emitRequireInstance(final RequireInstanceStatement require) {
622 super.writer.startRequireInstanceNode(require.rawArgument());
623 super.writer.endNode();
626 private void emitBit(final BitStatement bit) {
627 super.writer.startBitNode(bit.rawArgument());
628 emitPositionNode(bit.getPosition());
629 emitDocumentedNodeWithStatus(bit);
630 super.writer.endNode();
633 private void emitPositionNode(final @Nullable PositionStatement positionStatement) {
634 if (positionStatement != null) {
635 super.writer.startPositionNode(positionStatement.rawArgument());
636 super.writer.endNode();
640 private void emitStatusNode(final @Nullable StatusStatement statusStatement) {
641 if (statusStatement != null) {
642 super.writer.startStatusNode(statusStatement.rawArgument());
643 super.writer.endNode();
647 private void emitConfigNode(final @Nullable ConfigStatement configStatement) {
648 if (configStatement != null) {
649 super.writer.startConfigNode(configStatement.rawArgument());
650 super.writer.endNode();
654 private void emitMandatoryNode(final @Nullable MandatoryStatement mandatoryStatement) {
655 if (mandatoryStatement != null) {
656 super.writer.startMandatoryNode(mandatoryStatement.rawArgument());
657 super.writer.endNode();
661 private void emitPresenceNode(final @Nullable PresenceStatement presenceStatement) {
662 if (presenceStatement != null) {
663 super.writer.startPresenceNode(presenceStatement.rawArgument());
664 super.writer.endNode();
668 private void emitOrderedBy(final @Nullable OrderedByStatement orderedByStatement) {
669 if (orderedByStatement != null) {
670 super.writer.startOrderedByNode(orderedByStatement.rawArgument());
671 super.writer.endNode();
675 private void emitMust(final @Nullable MustStatement must) {
677 super.writer.startMustNode(must.rawArgument());
678 emitErrorMessageNode(must.getErrorMessageStatement());
679 emitErrorAppTagNode(must.getErrorAppTagStatement());
680 emitDescriptionNode(must.getDescription());
681 emitReferenceNode(must.getReference());
682 super.writer.endNode();
686 private void emitErrorMessageNode(final @Nullable ErrorMessageStatement errorMessageStatement) {
687 if (errorMessageStatement != null) {
688 super.writer.startErrorMessageNode(errorMessageStatement.rawArgument());
689 super.writer.endNode();
693 private void emitErrorAppTagNode(final @Nullable ErrorAppTagStatement errorAppTagStatement) {
694 if (errorAppTagStatement != null) {
695 super.writer.startErrorAppTagNode(errorAppTagStatement.rawArgument());
696 super.writer.endNode();
700 private void emitMinElementsNode(final @Nullable MinElementsStatement minElementsStatement) {
701 if (minElementsStatement != null) {
702 super.writer.startMinElementsNode(minElementsStatement.rawArgument());
703 super.writer.endNode();
707 private void emitMaxElementsNode(final @Nullable MaxElementsStatement maxElementsStatement) {
708 if (maxElementsStatement != null) {
709 super.writer.startMaxElementsNode(maxElementsStatement.rawArgument());
710 super.writer.endNode();
714 private void emitValueNode(final @Nullable ValueStatement valueStatement) {
715 if (valueStatement != null) {
716 super.writer.startValueNode(valueStatement.rawArgument());
717 super.writer.endNode();
721 private void emitDocumentedNodeWithStatus(final DocumentationGroup.WithStatus input) {
722 emitStatusNode(input.getStatus());
723 emitDocumentedNode(input);
726 private void emitDocumentedNode(final DocumentationGroup input) {
727 emitDescriptionNode(input.getDescription());
728 emitReferenceNode(input.getReference());
731 private void emitDocumentedConstraint(final DocumentedConstraintGroup input) {
732 emitDescriptionNode(input.getDescription());
733 emitReferenceNode(input.getReference());
734 emitErrorMessageNode(input.getErrorMessageStatement());
735 emitErrorAppTagNode(input.getErrorAppTagStatement());
738 private void emitGrouping(final GroupingStatement grouping) {
739 super.writer.startGroupingNode(grouping.rawArgument());
740 emitDocumentedNodeWithStatus(grouping);
741 emitDataNodeContainer(grouping);
742 emitUnknownStatementNodes(grouping);
743 emitNotifications(grouping.getNotifications());
744 emitActions(grouping.getActions());
745 super.writer.endNode();
749 private void emitContainer(final ContainerStatement container) {
750 super.writer.startContainerNode(container.rawArgument());
751 emitWhen(container.getWhenStatement());
752 emitMustNodes(container.getMusts());
753 emitIfFeatures(container.getIfFeatures());
754 emitPresenceNode(container.getPresence());
755 emitConfigNode(container.getConfig());
756 emitDocumentedNodeWithStatus(container);
757 emitDataNodeContainer(container);
758 emitUnknownStatementNodes(container);
759 emitNotifications(container.getNotifications());
760 emitActions(container.getActions());
761 super.writer.endNode();
765 private void emitLeaf(final LeafStatement leaf) {
766 super.writer.startLeafNode(leaf.rawArgument());
767 emitWhen(leaf.getWhenStatement());
768 emitIfFeatures(leaf.getIfFeatures());
769 emitType(leaf.getType());
770 emitUnitsNode(leaf.getUnits());
771 emitMustNodes(leaf.getMusts());
772 emitDefaultNode(leaf.getDefault());
773 emitConfigNode(leaf.getConfig());
774 emitMandatoryNode(leaf.getMandatory());
775 emitDocumentedNodeWithStatus(leaf);
776 emitUnknownStatementNodes(leaf);
777 super.writer.endNode();
780 private void emitLeafList(final LeafListStatement leafList) {
781 super.writer.startLeafListNode(leafList.rawArgument());
782 emitWhen(leafList.getWhenStatement());
783 emitIfFeatures(leafList.getIfFeatures());
784 emitType(leafList.getType());
785 emitUnitsNode(leafList.getUnits());
786 emitMustNodes(leafList.getMusts());
787 emitConfigNode(leafList.getConfig());
788 emitDefaultNodes(leafList.getDefaults());
789 emitMinElementsNode(leafList.getMinElements());
790 emitMaxElementsNode(leafList.getMaxElements());
791 emitOrderedBy(leafList.getOrderedBy());
792 emitDocumentedNodeWithStatus(leafList);
793 emitUnknownStatementNodes(leafList);
794 super.writer.endNode();
797 private void emitList(final ListStatement list) {
798 super.writer.startListNode(list.rawArgument());
799 emitWhen(list.getWhenStatement());
800 emitIfFeatures(list.getIfFeatures());
801 emitMustNodes(list.getMusts());
802 emitKey(list.getKey());
803 emitUniqueConstraints(list.getUnique());
804 emitConfigNode(list.getConfig());
805 emitMinElementsNode(list.getMinElements());
806 emitMaxElementsNode(list.getMaxElements());
807 emitOrderedBy(list.getOrderedBy());
808 emitDocumentedNodeWithStatus(list);
809 emitDataNodeContainer(list);
810 emitUnknownStatementNodes(list);
811 emitNotifications(list.getNotifications());
812 emitActions(list.getActions());
813 super.writer.endNode();
816 private void emitMustNodes(final Collection<? extends MustStatement> collection) {
817 for (final MustStatement must : collection) {
822 private void emitKey(final KeyStatement keyStatement) {
823 if (keyStatement != null) {
824 super.writer.startKeyNode(keyStatement.rawArgument());
825 super.writer.endNode();
829 private void emitUniqueConstraints(final Collection<? extends UniqueStatement> collection) {
830 for (final UniqueStatement uniqueConstraint : collection) {
831 emitUnique(uniqueConstraint);
835 private void emitUnique(final UniqueStatement uniqueConstraint) {
836 if (uniqueConstraint != null) {
837 super.writer.startUniqueNode(uniqueConstraint.rawArgument());
838 super.writer.endNode();
842 private void emitChoice(final ChoiceStatement choice) {
843 super.writer.startChoiceNode(choice.rawArgument());
844 emitWhen(choice.getWhenStatement());
845 emitIfFeatures(choice.getIfFeatures());
846 emitDefaultNode(choice.getDefault());
847 emitConfigNode(choice.getConfig());
848 emitMandatoryNode(choice.getMandatory());
849 emitDocumentedNodeWithStatus(choice);
850 emitCases(choice.getCases());
851 emitUnknownStatementNodes(choice);
852 super.writer.endNode();
855 private void emitShortCases(final Collection<? extends DeclaredStatement<?>> declaredSubstatements) {
856 for (final DeclaredStatement<?> child : declaredSubstatements) {
857 if (child instanceof ContainerStatement) {
858 emitContainer((ContainerStatement) child);
859 } else if (child instanceof LeafStatement) {
860 emitLeaf((LeafStatement) child);
861 } else if (child instanceof LeafListStatement) {
862 emitLeafList((LeafListStatement) child);
863 } else if (child instanceof ListStatement) {
864 emitList((ListStatement) child);
865 } else if (child instanceof ChoiceStatement) {
866 emitChoice((ChoiceStatement) child);
867 } else if (child instanceof AnyxmlStatement) {
868 emitAnyxml((AnyxmlStatement) child);
869 } else if (child instanceof AnydataStatement) {
870 emitAnydata((AnydataStatement) child);
875 private void emitCases(final Collection<? extends CaseStatement> cases) {
876 for (final CaseStatement caze : cases) {
877 if (isExplicitStatement(caze)) {
880 final Collection<? extends DeclaredStatement<?>> shortCaseChilds = caze.declaredSubstatements();
881 checkState(shortCaseChilds.size() == 1, "Only one child is allowed for each short case node");
882 emitShortCases(shortCaseChilds);
887 private void emitCaseNode(final CaseStatement caze) {
888 super.writer.startCaseNode(caze.rawArgument());
889 emitWhen(caze.getWhenStatement());
890 emitIfFeatures(caze.getIfFeatures());
891 emitDocumentedNodeWithStatus(caze);
892 emitDataNodeContainer(caze);
893 emitUnknownStatementNodes(caze);
894 super.writer.endNode();
897 private void emitAnyxml(final AnyxmlStatement anyxml) {
898 super.writer.startAnyxmlNode(anyxml.rawArgument());
899 emitDocumentedNodeWithStatus(anyxml);
900 emitWhen(anyxml.getWhenStatement());
901 emitIfFeatures(anyxml.getIfFeatures());
902 emitMustNodes(anyxml.getMusts());
903 emitConfigNode(anyxml.getConfig());
904 emitMandatoryNode(anyxml.getMandatory());
905 emitDocumentedNodeWithStatus(anyxml);
906 emitUnknownStatementNodes(anyxml);
907 super.writer.endNode();
910 private void emitAnydata(final AnydataStatement anydata) {
911 super.writer.startAnydataNode(anydata.rawArgument());
912 emitWhen(anydata.getWhenStatement());
913 emitIfFeatures(anydata.getIfFeatures());
914 emitMustNodes(anydata.getMusts());
915 emitConfigNode(anydata.getConfig());
916 emitMandatoryNode(anydata.getMandatory());
917 emitDocumentedNodeWithStatus(anydata);
918 emitUnknownStatementNodes(anydata);
919 super.writer.endNode();
922 private void emitUsesNode(final UsesStatement uses) {
923 super.writer.startUsesNode(uses.rawArgument());
924 emitWhen(uses.getWhenStatement());
925 emitIfFeatures(uses.getIfFeatures());
926 emitDocumentedNodeWithStatus(uses);
927 for (final RefineStatement refine : uses.getRefines()) {
930 for (final AugmentStatement aug : uses.getAugments()) {
931 emitUsesAugmentNode(aug);
933 super.writer.endNode();
936 private void emitRefine(final RefineStatement refine) {
937 super.writer.startRefineNode(refine.rawArgument());
938 emitDocumentedNode(refine);
939 emitIfFeatures(refine.getIfFeatures());
940 emitMustNodes(refine.getMusts());
941 emitPresenceNode(refine.getPresence());
942 emitDefaultNodes(refine.getDefaults());
943 emitConfigNode(refine.getConfig());
944 emitMandatoryNode(refine.getMandatory());
945 emitMinElementsNode(refine.getMinElements());
946 emitMaxElementsNode(refine.getMaxElements());
947 super.writer.endNode();
950 private void emitUsesAugmentNode(final AugmentStatement aug) {
952 * differs only in location in schema, otherwise currently (as of
953 * RFC6020) it is same, so we could freely reuse path.
958 private void emitAugment(final AugmentStatement augmentation) {
959 super.writer.startAugmentNode(augmentation.rawArgument());
960 emitIfFeatures(augmentation.getIfFeatures());
961 emitWhen(augmentation.getWhenStatement());
962 emitDocumentedNodeWithStatus(augmentation);
963 emitDataNodeContainer(augmentation);
964 emitCases(augmentation.getCases());
965 emitUnknownStatementNodes(augmentation);
966 emitNotifications(augmentation.getNotifications());
967 emitActions(augmentation.getActions());
968 super.writer.endNode();
971 private void emitUnknownStatementNodes(final DeclaredStatement<?> declaredStmt) {
972 declaredStmt.streamDeclaredSubstatements(UnknownStatement.class).forEach(this::emitUnknownStatementNode);
975 private void emitUnknownStatementNode(final UnknownStatement<?> unknonwnStmt) {
976 final StatementDefinition def = unknonwnStmt.statementDefinition();
977 if (def.getArgumentName() == null) {
978 super.writer.startUnknownNode(def);
980 super.writer.startUnknownNode(def, unknonwnStmt.rawArgument());
982 emitUnknownStatementNodes(unknonwnStmt);
983 super.writer.endNode();
986 private void emitWhen(final WhenStatement whenStatement) {
987 if (whenStatement != null) {
988 super.writer.startWhenNode(whenStatement.rawArgument());
989 emitDocumentedNode(whenStatement);
990 super.writer.endNode();
994 private void emitRpc(final RpcStatement rpc) {
995 super.writer.startRpcNode(rpc.rawArgument());
996 emitOperationBody(rpc);
997 emitUnknownStatementNodes(rpc);
998 super.writer.endNode();
1001 private void emitOperationBody(final OperationGroup operationStmt) {
1002 emitIfFeatures(operationStmt.getIfFeatures());
1003 emitStatusNode(operationStmt.getStatus());
1004 emitDescriptionNode(operationStmt.getDescription());
1005 emitReferenceNode(operationStmt.getReference());
1007 for (final TypedefStatement typedef : operationStmt.getTypedefs()) {
1008 emitTypedefNode(typedef);
1010 for (final GroupingStatement grouping : operationStmt.getGroupings()) {
1011 emitGrouping(grouping);
1013 emitInput(operationStmt.getInput());
1014 emitOutput(operationStmt.getOutput());
1017 private void emitActions(final Collection<? extends ActionStatement> collection) {
1018 for (final ActionStatement actionDefinition : collection) {
1019 emitAction(actionDefinition);
1023 private void emitAction(final ActionStatement actionDefinition) {
1024 super.writer.startActionNode(actionDefinition.rawArgument());
1025 emitOperationBody(actionDefinition);
1026 emitUnknownStatementNodes(actionDefinition);
1027 super.writer.endNode();
1030 private void emitInput(final InputStatement inputStatement) {
1031 if (isExplicitStatement(inputStatement)) {
1032 super.writer.startInputNode();
1033 emitMustNodes(inputStatement.getMusts());
1034 emitDataNodeContainer(inputStatement);
1035 emitUnknownStatementNodes(inputStatement);
1036 super.writer.endNode();
1040 private void emitOutput(final OutputStatement output) {
1041 if (isExplicitStatement(output)) {
1042 super.writer.startOutputNode();
1043 emitMustNodes(output.getMusts());
1044 emitDataNodeContainer(output);
1045 emitUnknownStatementNodes(output);
1046 super.writer.endNode();
1050 private static boolean isExplicitStatement(final DeclaredStatement<?> stmt) {
1051 return stmt != null && stmt.getStatementSource() == StatementSource.DECLARATION;
1054 private void emitNotifications(final Collection<? extends NotificationStatement> collection) {
1055 for (final NotificationStatement notification : collection) {
1056 emitNotificationNode(notification);
1060 private void emitNotificationNode(final NotificationStatement notification) {
1061 super.writer.startNotificationNode(notification.rawArgument());
1062 emitIfFeatures(notification.getIfFeatures());
1063 emitMustNodes(notification.getMusts());
1064 emitDocumentedNodeWithStatus(notification);
1065 emitDataNodeContainer(notification);
1066 emitUnknownStatementNodes(notification);
1067 super.writer.endNode();
1070 private void emitDeviation(final DeviationStatement deviation) {
1071 super.writer.startDeviationNode(deviation.rawArgument());
1072 emitDeviateStatements(deviation.getDeviateStatements());
1073 emitUnknownStatementNodes(deviation);
1074 super.writer.endNode();
1077 private void emitDeviateStatements(final Collection<? extends DeviateStatement> deviateStatements) {
1078 for (final DeviateStatement deviateStatement : deviateStatements) {
1079 emitDeviate(deviateStatement);
1083 private void emitDeviate(final DeviateStatement deviateStatement) {
1084 super.writer.startDeviateNode(deviateStatement.rawArgument());
1086 * :FIXME Currently, DeviateStatementImpl contains implementation
1087 * for all deviate types (i.e. add, replace, delete). However it
1088 * would be better to create subinterfaces of DeviateStatement for
1089 * each deviate type (i.e. AddDeviateStatement,
1090 * ReplaceDeviateStatement,..) and create argument specific supports
1091 * (i.e. definitions) for each deviate type (very similarly like by
1094 for (final DeclaredStatement<?> child : deviateStatement.declaredSubstatements()) {
1095 if (child instanceof MustStatement) {
1096 emitMust((MustStatement) child);
1097 } else if (child instanceof DefaultStatement) {
1098 emitDefaultNode((DefaultStatement) child);
1099 } else if (child instanceof UniqueStatement) {
1100 emitUnique((UniqueStatement) child);
1101 } else if (child instanceof UnitsStatement) {
1102 emitUnitsNode((UnitsStatement) child);
1103 } else if (child instanceof TypeStatement) {
1104 emitType((TypeStatement) child);
1105 } else if (child instanceof MinElementsStatement) {
1106 emitMinElementsNode((MinElementsStatement) child);
1107 } else if (child instanceof MaxElementsStatement) {
1108 emitMaxElementsNode((MaxElementsStatement) child);
1109 } else if (child instanceof MandatoryStatement) {
1110 emitMandatoryNode((MandatoryStatement) child);
1111 } else if (child instanceof ConfigStatement) {
1112 emitConfigNode((ConfigStatement) child);
1113 } else if (child instanceof UnknownStatement) {
1114 emitUnknownStatementNode((UnknownStatement<?>) child);
1117 super.writer.endNode();
1121 static class EffectiveSchemaContextEmitter extends SchemaContextEmitter {
1123 EffectiveSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
1124 final YangVersion yangVersion, final boolean emitInstantiated) {
1125 super(writer, extensions, yangVersion, emitInstantiated, true);
1128 void emitModule(final Module input) {
1129 super.writer.startModuleNode(input.getName());
1130 emitModuleHeader(input);
1131 emitLinkageNodes(input);
1132 emitMetaNodes(input);
1133 emitRevisionNodes(input);
1134 emitBodyNodes(input);
1135 super.writer.endNode();
1138 private void emitModuleHeader(final Module input) {
1139 emitYangVersionNode(input.getYangVersion());
1140 emitNamespace(input.getNamespace());
1141 emitPrefixNode(input.getPrefix());
1144 @SuppressWarnings("unused")
1145 private void emitSubmodule(final String input) {
1147 * FIXME: BUG-2444: Implement submodule export
1149 * submoduleHeaderNodes linkageNodes metaNodes revisionNodes
1150 * bodyNodes super.writer.endNode();
1154 @SuppressWarnings("unused")
1155 private void emitSubmoduleHeaderNodes(final Module input) {
1157 * FIXME: BUG-2444: Implement submodule headers properly
1159 * :yangVersionNode //Optional
1165 private void emitMetaNodes(final Module input) {
1166 input.getOrganization().ifPresent(this::emitOrganizationNode);
1167 input.getContact().ifPresent(this::emitContact);
1168 emitDocumentedNode(input);
1171 private void emitLinkageNodes(final Module input) {
1172 for (final ModuleImport importNode : input.getImports()) {
1173 emitImport(importNode);
1176 * FIXME: BUG-2444: Emit include statements
1180 private void emitRevisionNodes(final Module input) {
1182 * FIXME: BUG-2444: emit revisions properly, when parsed model will
1183 * provide enough information
1185 input.getRevision().ifPresent(this::emitRevision);
1188 private void emitBodyNodes(final Module input) {
1190 for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
1191 emitExtension(extension);
1193 for (final FeatureDefinition definition : input.getFeatures()) {
1194 emitFeature(definition);
1196 for (final IdentitySchemaNode identity : input.getIdentities()) {
1197 emitIdentity(identity);
1199 for (final Deviation deviation : input.getDeviations()) {
1200 emitDeviation(deviation);
1203 emitDataNodeContainer(input);
1205 for (final AugmentationSchemaNode augmentation : input.getAugmentations()) {
1206 emitAugment(augmentation);
1208 for (final RpcDefinition rpc : input.getRpcs()) {
1212 emitNotifications(input.getNotifications());
1215 private void emitDataNodeContainer(final DataNodeContainer input) {
1216 for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
1217 emitTypedefNode(typedef);
1219 for (final GroupingDefinition grouping : input.getGroupings()) {
1220 emitGrouping(grouping);
1222 for (final DataSchemaNode child : input.getChildNodes()) {
1223 emitDataSchemaNode(child);
1225 for (final UsesNode usesNode : input.getUses()) {
1226 emitUsesNode(usesNode);
1230 private void emitDataSchemaNode(final DataSchemaNode child) {
1231 if (!super.emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
1232 // We skip instantiated nodes.
1236 if (child instanceof ContainerSchemaNode) {
1237 emitContainer((ContainerSchemaNode) child);
1238 } else if (child instanceof LeafSchemaNode) {
1239 emitLeaf((LeafSchemaNode) child);
1240 } else if (child instanceof LeafListSchemaNode) {
1241 emitLeafList((LeafListSchemaNode) child);
1242 } else if (child instanceof ListSchemaNode) {
1243 emitList((ListSchemaNode) child);
1244 } else if (child instanceof ChoiceSchemaNode) {
1245 emitChoice((ChoiceSchemaNode) child);
1246 } else if (child instanceof AnyXmlSchemaNode) {
1247 emitAnyxml((AnyXmlSchemaNode) child);
1248 } else if (child instanceof AnyDataSchemaNode) {
1249 emitAnydata((AnyDataSchemaNode) child);
1251 throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
1255 private void emitYangVersionNode(final YangVersion input) {
1256 super.writer.startYangVersionNode(input.toString());
1257 super.writer.endNode();
1260 private void emitImport(final ModuleImport importNode) {
1261 super.writer.startImportNode(importNode.getModuleName());
1262 emitDocumentedNode(importNode);
1263 emitPrefixNode(importNode.getPrefix());
1264 importNode.getRevision().ifPresent(this::emitRevisionDateNode);
1265 super.writer.endNode();
1268 @SuppressWarnings("unused")
1269 private void emitInclude(final String input) {
1271 * FIXME: BUG-2444: Implement proper export of include statements
1272 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1275 * :revisionDateNode :super.writer.endNode();)
1279 private void emitNamespace(final URI uri) {
1280 super.writer.startNamespaceNode(uri);
1281 super.writer.endNode();
1285 private void emitPrefixNode(final String input) {
1286 super.writer.startPrefixNode(input);
1287 super.writer.endNode();
1291 @SuppressWarnings("unused")
1292 private void emitBelongsTo(final String input) {
1294 * FIXME: BUG-2444: Implement proper export of belongs-to statements
1295 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1298 * :super.writer.startBelongsToNode(IdentifierHelper.getIdentifier(
1302 * :prefixNode :super.writer.endNode();
1308 private void emitOrganizationNode(final String input) {
1309 super.writer.startOrganizationNode(input);
1310 super.writer.endNode();
1313 private void emitContact(final String input) {
1314 super.writer.startContactNode(input);
1315 super.writer.endNode();
1318 private void emitDescriptionNode(final String input) {
1319 super.writer.startDescriptionNode(input);
1320 super.writer.endNode();
1323 private void emitReferenceNode(final String input) {
1324 super.writer.startReferenceNode(input);
1325 super.writer.endNode();
1328 private void emitUnitsNode(final @Nullable String input) {
1329 super.writer.startUnitsNode(input);
1330 super.writer.endNode();
1333 private void emitRevision(final Revision date) {
1335 super.writer.startRevisionNode(date);
1337 // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode
1338 // //FIXME: BUG-2444: Optional
1339 // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode
1340 // //FIXME: BUG-2444: Optional
1341 super.writer.endNode();
1345 private void emitRevisionDateNode(final Revision date) {
1346 super.writer.startRevisionDateNode(date);
1347 super.writer.endNode();
1350 private void emitExtension(final ExtensionDefinition extension) {
1351 super.writer.startExtensionNode(extension.getQName());
1352 emitArgument(extension.getArgument(), extension.isYinElement());
1353 emitDocumentedNode(extension);
1354 emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
1355 super.writer.endNode();
1359 private void emitArgument(final @Nullable String input, final boolean yinElement) {
1360 if (input != null) {
1361 super.writer.startArgumentNode(input);
1362 emitYinElement(yinElement);
1363 super.writer.endNode();
1368 private void emitYinElement(final boolean yinElement) {
1369 super.writer.startYinElementNode(yinElement);
1370 super.writer.endNode();
1374 private void emitIdentity(final IdentitySchemaNode identity) {
1375 super.writer.startIdentityNode(identity.getQName());
1376 emitBaseIdentities(identity.getBaseIdentities());
1377 emitDocumentedNode(identity);
1378 super.writer.endNode();
1381 private void emitBaseIdentities(final Set<IdentitySchemaNode> identities) {
1382 for (final IdentitySchemaNode identitySchemaNode : identities) {
1383 emitBase(identitySchemaNode.getQName());
1387 private void emitBase(final QName qname) {
1388 super.writer.startBaseNode(qname);
1389 super.writer.endNode();
1392 private void emitFeature(final FeatureDefinition definition) {
1393 super.writer.startFeatureNode(definition.getQName());
1395 // FIXME: BUG-2444: FIXME: BUG-2444: Expose ifFeature
1396 // *(ifFeatureNode )
1397 emitDocumentedNode(definition);
1398 super.writer.endNode();
1401 @SuppressWarnings("unused")
1402 private void emitIfFeature(final String input) {
1404 * FIXME: BUG-2444: Implement proper export of include statements
1405 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1410 private void emitTypedefNode(final TypeDefinition<?> typedef) {
1411 super.writer.startTypedefNode(typedef.getQName());
1412 // Differentiate between derived type and existing type
1414 emitTypeNodeDerived(typedef);
1415 typedef.getUnits().ifPresent(this::emitUnitsNode);
1416 typedef.getDefaultValue().ifPresent(this::emitDefaultNode);
1417 emitDocumentedNode(typedef);
1418 emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
1419 super.writer.endNode();
1422 private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
1423 final SchemaPath path = subtype.getPath();
1424 if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
1425 emitTypeNodeDerived(subtype);
1427 emitTypeNodeReferenced(subtype);
1431 private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
1432 super.writer.startTypeNode(typeDefinition.getQName());
1433 super.writer.endNode();
1437 private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
1438 final TypeDefinition<?> b = typeDefinition.getBaseType();
1439 final TypeDefinition<?> baseType = b == null ? typeDefinition : b;
1440 super.writer.startTypeNode(baseType.getQName());
1441 emitTypeBodyNodes(typeDefinition);
1442 super.writer.endNode();
1446 private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
1447 if (typeDef instanceof DecimalTypeDefinition) {
1448 emitDecimal64Specification((DecimalTypeDefinition) typeDef);
1449 } else if (typeDef instanceof RangeRestrictedTypeDefinition) {
1450 emitRangeRestrictedSpecification((RangeRestrictedTypeDefinition<?, ?>) typeDef);
1451 } else if (typeDef instanceof StringTypeDefinition) {
1452 emitStringRestrictions((StringTypeDefinition) typeDef);
1453 } else if (typeDef instanceof EnumTypeDefinition) {
1454 emitEnumSpecification((EnumTypeDefinition) typeDef);
1455 } else if (typeDef instanceof LeafrefTypeDefinition) {
1456 emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
1457 } else if (typeDef instanceof IdentityrefTypeDefinition) {
1458 emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
1459 } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
1460 emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
1461 } else if (typeDef instanceof BitsTypeDefinition) {
1462 emitBitsSpecification((BitsTypeDefinition) typeDef);
1463 } else if (typeDef instanceof UnionTypeDefinition) {
1464 emitUnionSpecification((UnionTypeDefinition) typeDef);
1465 } else if (typeDef instanceof BinaryTypeDefinition) {
1466 ((BinaryTypeDefinition) typeDef).getLengthConstraint().ifPresent(this::emitLength);
1467 } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
1470 throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
1474 private void emitRangeRestrictedSpecification(final RangeRestrictedTypeDefinition<?, ?> typeDef) {
1475 typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
1478 private void emitRangeNode(final RangeConstraint<?> constraint) {
1479 super.writer.startRangeNode(toRangeString(constraint.getAllowedRanges()));
1480 constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1481 constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1482 emitDocumentedNode(constraint);
1483 super.writer.endNode();
1486 private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
1487 emitFranctionDigitsNode(typeDefinition.getFractionDigits());
1488 emitRangeRestrictedSpecification(typeDefinition);
1491 private void emitFranctionDigitsNode(final Integer fractionDigits) {
1492 super.writer.startFractionDigitsNode(fractionDigits);
1493 super.writer.endNode();
1496 private void emitStringRestrictions(final StringTypeDefinition typeDef) {
1497 typeDef.getLengthConstraint().ifPresent(this::emitLength);
1499 for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
1500 emitPatternNode(pattern);
1504 private void emitLength(final LengthConstraint constraint) {
1505 super.writer.startLengthNode(toLengthString(constraint.getAllowedRanges()));
1506 constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1507 constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1508 emitDocumentedNode(constraint);
1509 super.writer.endNode();
1512 private static String toLengthString(final RangeSet<Integer> ranges) {
1513 final Iterator<Range<Integer>> it = ranges.asRanges().iterator();
1514 if (!it.hasNext()) {
1518 final StringBuilder sb = new StringBuilder();
1521 final Range<Integer> current = it.next();
1522 haveNext = it.hasNext();
1523 appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
1526 return sb.toString();
1529 private static String toRangeString(final RangeSet<?> ranges) {
1530 final Iterator<? extends Range<?>> it = ranges.asRanges().iterator();
1531 if (!it.hasNext()) {
1535 final StringBuilder sb = new StringBuilder();
1538 final Range<?> current = it.next();
1539 haveNext = it.hasNext();
1540 appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
1543 return sb.toString();
1546 private static void appendRange(final StringBuilder sb, final Object min, final Object max,
1547 final boolean haveNext) {
1549 if (!min.equals(max)) {
1558 private void emitPatternNode(final PatternConstraint pattern) {
1559 super.writer.startPatternNode(pattern.getRegularExpressionString());
1560 pattern.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1561 pattern.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1562 emitDocumentedNode(pattern);
1563 pattern.getModifier().ifPresent(this::emitModifier);
1564 super.writer.endNode();
1567 private void emitModifier(final ModifierKind modifier) {
1568 super.writer.startModifierNode(modifier);
1569 super.writer.endNode();
1572 private void emitDefaultNodes(final Collection<? extends Object> defaults) {
1573 for (final Object defaultValue : defaults) {
1574 emitDefaultNode(defaultValue);
1578 private void emitDefaultNode(final @Nullable Object object) {
1579 super.writer.startDefaultNode(object.toString());
1580 super.writer.endNode();
1583 private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
1584 for (final EnumPair enumValue : typeDefinition.getValues()) {
1585 emitEnumNode(enumValue);
1589 private void emitEnumNode(final EnumPair enumValue) {
1590 super.writer.startEnumNode(enumValue.getName());
1591 emitValueNode(enumValue.getValue());
1592 emitDocumentedNode(enumValue);
1593 super.writer.endNode();
1596 private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
1597 emitPathNode(typeDefinition.getPathStatement());
1598 if (YangVersion.VERSION_1_1 == super.yangVersion) {
1599 emitRequireInstanceNode(typeDefinition.requireInstance());
1603 private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
1604 super.writer.startPathNode(revisionAwareXPath);
1605 super.writer.endNode();
1608 private void emitRequireInstanceNode(final boolean require) {
1609 super.writer.startRequireInstanceNode(require);
1610 super.writer.endNode();
1613 private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
1614 emitRequireInstanceNode(typeDefinition.requireInstance());
1617 private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
1618 emitBaseIdentities(typeDefinition.getIdentities());
1621 private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
1622 for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
1623 // FIXME: BUG-2444: What if we have locally modified types here?
1624 // is solution to look-up in schema path?
1625 emitTypeNode(typeDefinition.getPath(), subtype);
1629 private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
1630 for (final Bit bit : typeDefinition.getBits()) {
1635 private void emitBit(final Bit bit) {
1636 super.writer.startBitNode(bit.getName());
1637 emitPositionNode(bit.getPosition());
1638 emitDocumentedNode(bit);
1639 super.writer.endNode();
1642 private void emitPositionNode(final @Nullable Long position) {
1643 if (position != null) {
1644 super.writer.startPositionNode(UnsignedInteger.valueOf(position));
1645 super.writer.endNode();
1649 private void emitStatusNode(final @Nullable Status status) {
1650 if (status != null) {
1651 super.writer.startStatusNode(status);
1652 super.writer.endNode();
1656 private void emitConfigNode(final boolean config) {
1657 super.writer.startConfigNode(config);
1658 super.writer.endNode();
1661 private void emitMandatoryNode(final boolean mandatory) {
1662 super.writer.startMandatoryNode(mandatory);
1663 super.writer.endNode();
1666 private void emitPresenceNode(final boolean presence) {
1667 super.writer.startPresenceNode(presence);
1668 super.writer.endNode();
1671 private void emitOrderedBy(final boolean userOrdered) {
1673 super.writer.startOrderedByNode("user");
1675 super.writer.startOrderedByNode("system");
1677 super.writer.endNode();
1680 private void emitMust(final @Nullable MustDefinition mustCondition) {
1681 if (mustCondition != null && mustCondition.getXpath() != null) {
1682 super.writer.startMustNode(mustCondition.getXpath());
1683 mustCondition.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1684 mustCondition.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1685 emitDocumentedNode(mustCondition);
1686 super.writer.endNode();
1690 private void emitErrorMessageNode(final @Nullable String input) {
1691 super.writer.startErrorMessageNode(input);
1692 super.writer.endNode();
1695 private void emitErrorAppTagNode(final String input) {
1696 super.writer.startErrorAppTagNode(input);
1697 super.writer.endNode();
1700 private void emitMinElementsNode(final Integer min) {
1702 super.writer.startMinElementsNode(min);
1703 super.writer.endNode();
1707 private void emitMaxElementsNode(final @Nullable Integer max) {
1709 super.writer.startMaxElementsNode(max);
1710 super.writer.endNode();
1714 private void emitValueNode(final @Nullable Integer value) {
1715 if (value != null) {
1716 super.writer.startValueNode(value);
1717 super.writer.endNode();
1721 private void emitDocumentedNode(final DocumentedNode input) {
1722 input.getDescription().ifPresent(this::emitDescriptionNode);
1723 input.getReference().ifPresent(this::emitReferenceNode);
1726 private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
1727 emitStatusNode(input.getStatus());
1728 emitDocumentedNode((DocumentedNode) input);
1731 private void emitGrouping(final GroupingDefinition grouping) {
1732 super.writer.startGroupingNode(grouping.getQName());
1733 emitDocumentedNode(grouping);
1734 emitDataNodeContainer(grouping);
1735 emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
1736 emitNotifications(grouping.getNotifications());
1737 emitActions(grouping.getActions());
1738 super.writer.endNode();
1742 private void emitContainer(final ContainerSchemaNode child) {
1743 super.writer.startContainerNode(child.getQName());
1744 child.getMustConstraints().forEach(this::emitMust);
1745 child.getWhenCondition().ifPresent(this::emitWhen);
1746 // FIXME: BUG-2444: whenNode //:Optional
1747 // FIXME: BUG-2444: *(ifFeatureNode )
1748 emitPresenceNode(child.isPresenceContainer());
1749 emitConfigNode(child.isConfiguration());
1750 emitDocumentedNode(child);
1751 emitDataNodeContainer(child);
1752 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1753 emitNotifications(child.getNotifications());
1754 emitActions(child.getActions());
1755 super.writer.endNode();
1759 private void emitLeaf(final LeafSchemaNode child) {
1760 super.writer.startLeafNode(child.getQName());
1761 child.getWhenCondition().ifPresent(this::emitWhen);
1762 // FIXME: BUG-2444: *(ifFeatureNode )
1763 emitTypeNode(child.getPath(), child.getType());
1764 child.getType().getUnits().ifPresent(this::emitUnitsNode);
1765 child.getMustConstraints().forEach(this::emitMust);
1766 child.getType().getDefaultValue().ifPresent(this::emitDefaultNode);
1767 emitConfigNode(child.isConfiguration());
1768 emitMandatoryNode(child.isMandatory());
1769 emitDocumentedNode(child);
1770 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1771 super.writer.endNode();
1775 private void emitCountConstraint(final ElementCountConstraint constraint) {
1776 emitMinElementsNode(constraint.getMinElements());
1777 emitMaxElementsNode(constraint.getMaxElements());
1780 private void emitLeafList(final LeafListSchemaNode child) {
1781 super.writer.startLeafListNode(child.getQName());
1783 child.getWhenCondition().ifPresent(this::emitWhen);
1784 // FIXME: BUG-2444: *(ifFeatureNode )
1785 emitTypeNode(child.getPath(), child.getType());
1786 child.getType().getUnits().ifPresent(this::emitUnitsNode);
1787 // FIXME: BUG-2444: unitsNode /Optional
1788 child.getMustConstraints().forEach(this::emitMust);
1789 emitConfigNode(child.isConfiguration());
1790 emitDefaultNodes(child.getDefaults());
1791 child.getElementCountConstraint().ifPresent(this::emitCountConstraint);
1792 emitOrderedBy(child.isUserOrdered());
1793 emitDocumentedNode(child);
1794 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1795 super.writer.endNode();
1798 private void emitList(final ListSchemaNode child) {
1799 super.writer.startListNode(child.getQName());
1800 child.getWhenCondition().ifPresent(this::emitWhen);
1802 // FIXME: BUG-2444: *(ifFeatureNode )
1803 child.getMustConstraints().forEach(this::emitMust);
1804 emitKey(child.getKeyDefinition());
1805 emitUniqueConstraints(child.getUniqueConstraints());
1806 emitConfigNode(child.isConfiguration());
1807 child.getElementCountConstraint().ifPresent(this::emitCountConstraint);
1808 emitOrderedBy(child.isUserOrdered());
1809 emitDocumentedNode(child);
1810 emitDataNodeContainer(child);
1811 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1812 emitNotifications(child.getNotifications());
1813 emitActions(child.getActions());
1814 super.writer.endNode();
1818 private void emitKey(final List<QName> keyList) {
1819 if (keyList != null && !keyList.isEmpty()) {
1820 super.writer.startKeyNode(keyList);
1821 super.writer.endNode();
1825 private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
1826 for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
1827 emitUnique(uniqueConstraint);
1831 private void emitUnique(final UniqueConstraint uniqueConstraint) {
1832 super.writer.startUniqueNode(uniqueConstraint);
1833 super.writer.endNode();
1836 private void emitChoice(final ChoiceSchemaNode choice) {
1837 super.writer.startChoiceNode(choice.getQName());
1838 choice.getWhenCondition().ifPresent(this::emitWhen);
1839 // FIXME: BUG-2444: *(ifFeatureNode )
1840 // FIXME: BUG-2444: defaultNode //Optional
1841 emitConfigNode(choice.isConfiguration());
1842 emitMandatoryNode(choice.isMandatory());
1843 emitDocumentedNode(choice);
1844 for (final CaseSchemaNode caze : choice.getCases().values()) {
1845 // TODO: emit short case?
1848 emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
1849 super.writer.endNode();
1852 private void emitCaseNode(final CaseSchemaNode caze) {
1853 if (!super.emitInstantiated && caze.isAugmenting()) {
1856 super.writer.startCaseNode(caze.getQName());
1857 caze.getWhenCondition().ifPresent(this::emitWhen);
1858 // FIXME: BUG-2444: *(ifFeatureNode )
1859 emitDocumentedNode(caze);
1860 emitDataNodeContainer(caze);
1861 emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
1862 super.writer.endNode();
1866 private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
1867 super.writer.startAnyxmlNode(anyxml.getQName());
1868 emitBodyOfDataSchemaNode(anyxml);
1869 super.writer.endNode();
1872 private void emitAnydata(final AnyDataSchemaNode anydata) {
1873 super.writer.startAnydataNode(anydata.getQName());
1874 emitBodyOfDataSchemaNode(anydata);
1875 super.writer.endNode();
1878 private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
1879 dataSchemaNode.getWhenCondition().ifPresent(this::emitWhen);
1880 // FIXME: BUG-2444: *(ifFeatureNode )
1881 if (dataSchemaNode instanceof MustConstraintAware) {
1882 ((MustConstraintAware) dataSchemaNode).getMustConstraints().forEach(this::emitMust);
1884 emitConfigNode(dataSchemaNode.isConfiguration());
1885 emitDocumentedNode(dataSchemaNode);
1886 emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
1889 private void emitUsesNode(final UsesNode usesNode) {
1890 if (super.emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
1891 super.writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
1893 * FIXME: BUG-2444: whenNode / *(ifFeatureNode ) statusNode //
1894 * Optional F : descriptionNode // Optional referenceNode //
1897 for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
1900 for (final AugmentationSchemaNode aug : usesNode.getAugmentations()) {
1901 emitUsesAugmentNode(aug);
1903 super.writer.endNode();
1907 private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
1908 final SchemaPath path = refine.getKey();
1909 final SchemaNode value = refine.getValue();
1910 super.writer.startRefineNode(path);
1912 if (value instanceof LeafSchemaNode) {
1913 emitRefineLeafNodes((LeafSchemaNode) value);
1914 } else if (value instanceof LeafListSchemaNode) {
1915 emitRefineLeafListNodes((LeafListSchemaNode) value);
1916 } else if (value instanceof ListSchemaNode) {
1917 emitRefineListNodes((ListSchemaNode) value);
1918 } else if (value instanceof ChoiceSchemaNode) {
1919 emitRefineChoiceNodes((ChoiceSchemaNode) value);
1920 } else if (value instanceof CaseSchemaNode) {
1921 emitRefineCaseNodes((CaseSchemaNode) value);
1922 } else if (value instanceof ContainerSchemaNode) {
1923 emitRefineContainerNodes((ContainerSchemaNode) value);
1924 } else if (value instanceof AnyXmlSchemaNode) {
1925 emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
1927 super.writer.endNode();
1931 private static <T extends SchemaNode> T getOriginalChecked(final T value) {
1932 final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
1933 checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
1934 @SuppressWarnings("unchecked")
1935 final T ret = (T) original.get();
1939 private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
1940 if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
1941 value.getDescription().ifPresent(this::emitDescriptionNode);
1943 if (Objects.deepEquals(original.getReference(), value.getReference())) {
1944 value.getReference().ifPresent(this::emitReferenceNode);
1948 private void emitRefineContainerNodes(final ContainerSchemaNode value) {
1949 final ContainerSchemaNode original = getOriginalChecked(value);
1951 // emitMustNodes(child.getConstraints().getMustConstraints());
1952 if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
1953 emitPresenceNode(value.isPresenceContainer());
1955 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1956 emitConfigNode(value.isConfiguration());
1958 emitDocumentedNodeRefine(original, value);
1962 private void emitRefineLeafNodes(final LeafSchemaNode value) {
1963 final LeafSchemaNode original = getOriginalChecked(value);
1965 // emitMustNodes(child.getConstraints().getMustConstraints());
1966 if (Objects.deepEquals(original.getType().getDefaultValue(), value.getType().getDefaultValue())) {
1967 emitDefaultNode(value.getType().getDefaultValue());
1969 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1970 emitConfigNode(value.isConfiguration());
1972 emitDocumentedNodeRefine(original, value);
1973 if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
1974 emitMandatoryNode(value.isMandatory());
1978 private void emitRefinedMinMaxNodes(final Optional<ElementCountConstraint> value,
1979 final Optional<ElementCountConstraint> original) {
1980 Integer val = value.map(ElementCountConstraint::getMinElements).orElse(null);
1981 Integer orig = original.map(ElementCountConstraint::getMinElements).orElse(null);
1982 if (Objects.equals(val, orig)) {
1983 emitMinElementsNode(val);
1986 val = value.map(ElementCountConstraint::getMinElements).orElse(null);
1987 orig = original.map(ElementCountConstraint::getMinElements).orElse(null);
1988 if (Objects.equals(val, orig)) {
1989 emitMaxElementsNode(val);
1993 private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
1994 final LeafListSchemaNode original = getOriginalChecked(value);
1996 // emitMustNodes(child.getConstraints().getMustConstraints());
1997 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1998 emitConfigNode(value.isConfiguration());
2001 emitRefinedMinMaxNodes(value.getElementCountConstraint(), original.getElementCountConstraint());
2002 emitDocumentedNodeRefine(original, value);
2006 private void emitRefineListNodes(final ListSchemaNode value) {
2007 final ListSchemaNode original = getOriginalChecked(value);
2009 // emitMustNodes(child.getConstraints().getMustConstraints());
2010 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2011 emitConfigNode(value.isConfiguration());
2013 emitRefinedMinMaxNodes(value.getElementCountConstraint(), original.getElementCountConstraint());
2014 emitDocumentedNodeRefine(original, value);
2018 private void emitRefineChoiceNodes(final ChoiceSchemaNode value) {
2019 final ChoiceSchemaNode original = getOriginalChecked(value);
2021 // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
2022 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2023 emitConfigNode(value.isConfiguration());
2025 if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
2026 emitMandatoryNode(value.isMandatory());
2028 emitDocumentedNodeRefine(original, value);
2032 private void emitRefineCaseNodes(final CaseSchemaNode value) {
2033 final CaseSchemaNode original = getOriginalChecked(value);
2034 emitDocumentedNodeRefine(original, value);
2038 private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
2039 final AnyXmlSchemaNode original = getOriginalChecked(value);
2042 // emitMustNodes(child.getConstraints().getMustConstraints());
2043 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2044 emitConfigNode(value.isConfiguration());
2046 if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
2047 emitMandatoryNode(value.isMandatory());
2049 emitDocumentedNodeRefine(original, value);
2053 private void emitUsesAugmentNode(final AugmentationSchemaNode aug) {
2055 * differs only in location in schema, otherwise currently (as of
2056 * RFC6020) it is same, so we could freely reuse path.
2061 private void emitAugment(final AugmentationSchemaNode augmentation) {
2062 super.writer.startAugmentNode(augmentation.getTargetPath());
2063 // FIXME: BUG-2444: whenNode //Optional
2064 // FIXME: BUG-2444: *(ifFeatureNode )
2066 emitDocumentedNode(augmentation);
2067 for (final UsesNode uses : augmentation.getUses()) {
2071 for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
2072 if (childNode instanceof CaseSchemaNode) {
2073 emitCaseNode((CaseSchemaNode) childNode);
2075 emitDataSchemaNode(childNode);
2078 emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
2079 emitNotifications(augmentation.getNotifications());
2080 emitActions(augmentation.getActions());
2081 super.writer.endNode();
2084 private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
2085 for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
2086 if (!unknonwnNode.isAddedByAugmentation() && !unknonwnNode.isAddedByUses()) {
2087 emitUnknownStatementNode(unknonwnNode);
2092 private void emitUnknownStatementNode(final UnknownSchemaNode node) {
2093 final StatementDefinition def = getStatementChecked(node.getNodeType());
2094 if (def.getArgumentName() == null) {
2095 super.writer.startUnknownNode(def);
2097 super.writer.startUnknownNode(def, node.getNodeParameter());
2099 emitUnknownStatementNodes(node.getUnknownSchemaNodes());
2100 super.writer.endNode();
2103 private StatementDefinition getStatementChecked(final QName nodeType) {
2104 final StatementDefinition ret = super.extensions.get(nodeType);
2105 checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
2109 private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
2110 if (revisionAwareXPath != null) {
2111 super.writer.startWhenNode(revisionAwareXPath);
2112 super.writer.endNode();
2114 // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
2115 // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
2116 // FIXME: BUG-2444: super.writer.endNode();)
2120 private void emitRpc(final RpcDefinition rpc) {
2121 super.writer.startRpcNode(rpc.getQName());
2122 emitOperationBody(rpc);
2123 super.writer.endNode();
2126 private void emitOperationBody(final OperationDefinition rpc) {
2127 // FIXME: BUG-2444: *(ifFeatureNode )
2128 emitDocumentedNode(rpc);
2130 for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
2131 emitTypedefNode(typedef);
2133 for (final GroupingDefinition grouping : rpc.getGroupings()) {
2134 emitGrouping(grouping);
2136 emitInput(rpc.getInput());
2137 emitOutput(rpc.getOutput());
2138 emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
2141 private void emitActions(final Set<ActionDefinition> actions) {
2142 for (final ActionDefinition actionDefinition : actions) {
2143 emitAction(actionDefinition);
2147 private void emitAction(final ActionDefinition action) {
2148 if (!super.emitInstantiated && (action.isAddedByUses() || action.isAugmenting())) {
2149 // We skip instantiated nodes.
2152 super.writer.startActionNode(action.getQName());
2153 emitOperationBody(action);
2154 super.writer.endNode();
2157 private void emitInput(final @NonNull ContainerSchemaNode input) {
2158 if (isExplicitStatement(input)) {
2159 super.writer.startInputNode();
2160 input.getMustConstraints().forEach(this::emitMust);
2161 emitDataNodeContainer(input);
2162 emitUnknownStatementNodes(input.getUnknownSchemaNodes());
2163 super.writer.endNode();
2168 private void emitOutput(final @NonNull ContainerSchemaNode output) {
2169 if (isExplicitStatement(output)) {
2170 super.writer.startOutputNode();
2171 output.getMustConstraints().forEach(this::emitMust);
2172 emitDataNodeContainer(output);
2173 emitUnknownStatementNodes(output.getUnknownSchemaNodes());
2174 super.writer.endNode();
2178 private static boolean isExplicitStatement(final ContainerSchemaNode node) {
2179 return node instanceof EffectiveStatement && ((EffectiveStatement<?, ?>) node).getDeclared()
2180 .getStatementSource() == StatementSource.DECLARATION;
2183 private void emitNotifications(final Set<NotificationDefinition> notifications) {
2184 for (final NotificationDefinition notification : notifications) {
2185 emitNotificationNode(notification);
2189 private void emitNotificationNode(final NotificationDefinition notification) {
2190 if (!super.emitInstantiated && (notification.isAddedByUses() || notification.isAugmenting())) {
2191 // We skip instantiated nodes.
2195 super.writer.startNotificationNode(notification.getQName());
2196 // FIXME: BUG-2444: *(ifFeatureNode )
2197 for (final MustDefinition mustCondition : notification.getMustConstraints()) {
2198 emitMust(mustCondition);
2200 emitDocumentedNode(notification);
2201 emitDataNodeContainer(notification);
2202 emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
2203 super.writer.endNode();
2207 private void emitDeviation(final Deviation deviation) {
2209 * FIXME: BUG-2444: Deviation is not modeled properly and we are
2210 * loosing lot of information in order to export it properly
2212 * super.writer.startDeviationNode(deviation.getTargetPath());
2214 * :descriptionNode //:Optional
2217 * emitReferenceNode(deviation.getReference());
2218 * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
2219 * :deviateDeleteNode)) :super.writer.endNode();