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 com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Predicates;
13 import com.google.common.collect.Collections2;
14 import com.google.common.collect.Range;
15 import com.google.common.collect.RangeSet;
16 import com.google.common.primitives.UnsignedInteger;
18 import java.util.Collection;
19 import java.util.Iterator;
20 import java.util.List;
22 import java.util.Map.Entry;
23 import java.util.Objects;
24 import java.util.Optional;
26 import javax.annotation.Nonnull;
27 import javax.annotation.Nullable;
28 import javax.annotation.concurrent.NotThreadSafe;
29 import org.opendaylight.yangtools.yang.common.QName;
30 import org.opendaylight.yangtools.yang.common.Revision;
31 import org.opendaylight.yangtools.yang.common.YangVersion;
32 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
33 import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
37 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
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.ExtensionDefinition;
45 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
46 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
47 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
50 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
51 import org.opendaylight.yangtools.yang.model.api.Module;
52 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
53 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
54 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
55 import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
56 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
57 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
58 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
59 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
60 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
61 import org.opendaylight.yangtools.yang.model.api.Status;
62 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
63 import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
64 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
65 import org.opendaylight.yangtools.yang.model.api.UsesNode;
66 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
67 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
68 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
69 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
70 import org.opendaylight.yangtools.yang.model.api.stmt.ActionStatement;
71 import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement;
72 import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement;
73 import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
74 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
75 import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement;
76 import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
77 import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement;
78 import org.opendaylight.yangtools.yang.model.api.stmt.BodyGroup;
79 import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
80 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
81 import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
82 import org.opendaylight.yangtools.yang.model.api.stmt.ContactStatement;
83 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
84 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionContainer;
85 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement;
86 import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
87 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
88 import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
89 import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
90 import org.opendaylight.yangtools.yang.model.api.stmt.DocumentationGroup;
91 import org.opendaylight.yangtools.yang.model.api.stmt.DocumentedConstraintGroup;
92 import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement;
93 import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement;
94 import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
95 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement;
96 import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement;
97 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
98 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
99 import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
100 import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
101 import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
102 import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
103 import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
104 import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
105 import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
106 import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
107 import org.opendaylight.yangtools.yang.model.api.stmt.LinkageGroup;
108 import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
109 import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
110 import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsStatement;
111 import org.opendaylight.yangtools.yang.model.api.stmt.MetaGroup;
112 import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
113 import org.opendaylight.yangtools.yang.model.api.stmt.ModifierStatement;
114 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
115 import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement;
116 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
117 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
118 import org.opendaylight.yangtools.yang.model.api.stmt.OperationGroup;
119 import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
120 import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationStatement;
121 import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
122 import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement;
123 import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement;
124 import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement;
125 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
126 import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
127 import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
128 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
129 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
130 import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement;
131 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement;
132 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionGroup;
133 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
134 import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
135 import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
136 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
137 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
138 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
139 import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
140 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement;
141 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
142 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
143 import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement;
144 import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
145 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
146 import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
147 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
148 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
149 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
150 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
151 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
152 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
153 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
154 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
155 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
156 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
157 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
158 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
159 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
160 import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
161 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
162 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
163 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
164 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
165 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
166 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
170 abstract class SchemaContextEmitter {
172 final YangModuleWriter writer;
173 final boolean emitInstantiated;
174 final boolean emitUses;
175 final Map<QName, StatementDefinition> extensions;
176 final YangVersion yangVersion;
178 SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
179 final YangVersion yangVersion) {
180 this(writer, extensions, yangVersion, false, true);
183 SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
184 final YangVersion yangVersion, final boolean emitInstantiated, final boolean emitUses) {
185 this.writer = Preconditions.checkNotNull(writer);
186 this.emitInstantiated = emitInstantiated;
187 this.emitUses = emitUses;
188 this.extensions = Preconditions.checkNotNull(extensions);
189 this.yangVersion = yangVersion;
192 static void writeToStatementWriter(final Module module, final SchemaContext ctx,
193 final StatementTextWriter statementWriter, final boolean emitInstantiated) {
194 final YangModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
195 final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
196 if (module instanceof EffectiveStatement && !emitInstantiated) {
198 * if module is an effective statement and we don't want to export
199 * instantiated statements (e.g. statements added by uses or
200 * augment) we can get declared form i.e. ModuleStatement and then
201 * use DeclaredSchemaContextEmitter
203 new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion())
204 .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
207 * if we don't have access to declared form of supplied module or we
208 * want to emit also instantiated statements (e.g. statements added
209 * by uses or augment), we use EffectiveSchemaContextEmitter.
211 new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion(), emitInstantiated)
216 // FIXME: Probably should be moved to utils bundle.
217 static <T> boolean isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
218 final Iterator<T> prefixIt = prefix.iterator();
219 final Iterator<T> otherIt = other.iterator();
220 while (prefixIt.hasNext()) {
221 if (!otherIt.hasNext()) {
224 if (!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
231 static class DeclaredSchemaContextEmitter extends SchemaContextEmitter {
233 DeclaredSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
234 final YangVersion yangVersion) {
235 super(writer, extensions, yangVersion);
238 void emitModule(final DeclaredStatement<?> declaredRootStmt) {
239 if (declaredRootStmt instanceof ModuleStatement) {
240 emitModule((ModuleStatement) declaredRootStmt);
241 } else if (declaredRootStmt instanceof SubmoduleStatement) {
242 emitSubmodule((SubmoduleStatement) declaredRootStmt);
244 throw new UnsupportedOperationException(
245 String.format("Yin export: unsupported declared statement %s", declaredRootStmt));
249 private void emitModule(final ModuleStatement module) {
250 super.writer.startModuleNode(module.rawArgument());
251 emitModuleHeader(module);
252 emitLinkageNodes(module);
253 emitMetaNodes(module);
254 emitRevisionNodes(module);
255 emitBodyNodes(module);
256 emitUnknownStatementNodes(module);
257 super.writer.endNode();
260 private void emitModuleHeader(final ModuleStatement input) {
261 emitYangVersionNode(input.getYangVersion());
262 emitNamespace(input.getNamespace());
263 emitPrefixNode(input.getPrefix());
266 private void emitSubmodule(final SubmoduleStatement submodule) {
267 super.writer.startSubmoduleNode(submodule.rawArgument());
268 emitSubmoduleHeaderNodes(submodule);
269 emitLinkageNodes(submodule);
270 emitMetaNodes(submodule);
271 emitRevisionNodes(submodule);
272 emitBodyNodes(submodule);
273 emitUnknownStatementNodes(submodule);
274 super.writer.endNode();
277 private void emitSubmoduleHeaderNodes(final SubmoduleStatement input) {
278 emitYangVersionNode(input.getYangVersion());
279 emitBelongsTo(input.getBelongsTo());
282 private void emitBelongsTo(final BelongsToStatement belongsTo) {
283 super.writer.startBelongsToNode(belongsTo.rawArgument());
284 emitPrefixNode(belongsTo.getPrefix());
285 super.writer.endNode();
288 private void emitMetaNodes(final MetaGroup input) {
289 emitOrganizationNode(input.getOrganization());
290 emitContact(input.getContact());
291 emitDescriptionNode(input.getDescription());
292 emitReferenceNode(input.getReference());
295 private void emitLinkageNodes(final LinkageGroup input) {
296 for (final ImportStatement importNode : input.getImports()) {
297 emitImport(importNode);
299 for (final IncludeStatement importNode : input.getIncludes()) {
300 emitInclude(importNode);
304 private void emitRevisionNodes(final RevisionGroup input) {
305 emitRevisions(input.getRevisions());
308 private void emitBodyNodes(final BodyGroup input) {
310 for (final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension : input
312 emitExtension(extension);
314 for (final FeatureStatement definition : input.getFeatures()) {
315 emitFeature(definition);
317 for (final IdentityStatement identity : input.getIdentities()) {
318 emitIdentity(identity);
320 for (final DeviationStatement deviation : input.getDeviations()) {
321 emitDeviation(deviation);
324 emitDataNodeContainer(input);
326 for (final AugmentStatement augmentation : input.getAugments()) {
327 emitAugment(augmentation);
329 for (final RpcStatement rpc : input.getRpcs()) {
333 emitNotifications(input.getNotifications());
336 private void emitDataNodeContainer(final DataDefinitionContainer input) {
337 for (final DataDefinitionStatement child : input.getDataDefinitions()) {
338 emitDataSchemaNode(child);
342 private void emitDataNodeContainer(final DataDefinitionContainer.WithReusableDefinitions input) {
343 for (final TypedefStatement typedef : input.getTypedefs()) {
344 emitTypedefNode(typedef);
346 for (final GroupingStatement grouping : input.getGroupings()) {
347 emitGrouping(grouping);
349 for (final DataDefinitionStatement child : input.getDataDefinitions()) {
350 emitDataSchemaNode(child);
354 private void emitDataSchemaNode(final DataDefinitionStatement child) {
355 if (child instanceof ContainerStatement) {
356 emitContainer((ContainerStatement) child);
357 } else if (child instanceof LeafStatement) {
358 emitLeaf((LeafStatement) child);
359 } else if (child instanceof LeafListStatement) {
360 emitLeafList((LeafListStatement) child);
361 } else if (child instanceof ListStatement) {
362 emitList((ListStatement) child);
363 } else if (child instanceof ChoiceStatement) {
364 emitChoice((ChoiceStatement) child);
365 } else if (child instanceof AnyxmlStatement) {
366 emitAnyxml((AnyxmlStatement) child);
367 } else if (child instanceof AnydataStatement) {
368 emitAnydata((AnydataStatement) child);
369 } else if (child instanceof UsesStatement) {
370 emitUsesNode((UsesStatement) child);
372 throw new UnsupportedOperationException("Not supported DataStatement type " + child.getClass());
376 private void emitYangVersionNode(@Nullable final YangVersionStatement yangVersionStatement) {
377 if (yangVersionStatement != null) {
378 super.writer.startYangVersionNode(yangVersionStatement.rawArgument());
379 super.writer.endNode();
383 private void emitImport(final ImportStatement importNode) {
384 super.writer.startImportNode(importNode.rawArgument());
385 emitDocumentedNode(importNode);
386 emitPrefixNode(importNode.getPrefix());
387 emitRevisionDateNode(importNode.getRevisionDate());
388 super.writer.endNode();
391 private void emitInclude(final IncludeStatement include) {
392 super.writer.startIncludeNode(include.rawArgument());
393 emitDocumentedNode(include);
394 emitRevisionDateNode(include.getRevisionDate());
395 super.writer.endNode();
398 private void emitNamespace(final NamespaceStatement namespaceStatement) {
399 Preconditions.checkNotNull(namespaceStatement, "Namespace must not be null");
400 super.writer.startNamespaceNode(namespaceStatement.getUri());
401 super.writer.endNode();
404 private void emitPrefixNode(final PrefixStatement prefixStatement) {
405 Preconditions.checkNotNull(prefixStatement, "Prefix must not be null");
406 super.writer.startPrefixNode(prefixStatement.rawArgument());
407 super.writer.endNode();
410 private void emitOrganizationNode(@Nullable final OrganizationStatement organizationStatement) {
411 if (organizationStatement != null) {
412 super.writer.startOrganizationNode(organizationStatement.rawArgument());
413 super.writer.endNode();
417 private void emitContact(@Nullable final ContactStatement contactStatement) {
418 if (contactStatement != null) {
419 super.writer.startContactNode(contactStatement.rawArgument());
420 super.writer.endNode();
424 private void emitDescriptionNode(@Nullable final DescriptionStatement descriptionStatement) {
425 if (descriptionStatement != null) {
426 super.writer.startDescriptionNode(descriptionStatement.rawArgument());
427 super.writer.endNode();
431 private void emitReferenceNode(@Nullable final ReferenceStatement referenceStatement) {
432 if (referenceStatement != null) {
433 super.writer.startReferenceNode(referenceStatement.rawArgument());
434 super.writer.endNode();
438 private void emitUnitsNode(@Nullable final 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(@Nullable final 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(@Nullable final ArgumentStatement input) {
474 super.writer.startArgumentNode(input.rawArgument());
475 emitYinElement(input.getYinElement());
476 super.writer.endNode();
480 private void emitYinElement(@Nullable final 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(@Nullable final 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(@Nullable final PositionStatement positionStatement) {
634 if (positionStatement != null) {
635 super.writer.startPositionNode(positionStatement.rawArgument());
636 super.writer.endNode();
640 private void emitStatusNode(@Nullable final StatusStatement statusStatement) {
641 if (statusStatement != null) {
642 super.writer.startStatusNode(statusStatement.rawArgument());
643 super.writer.endNode();
647 private void emitConfigNode(@Nullable final ConfigStatement configStatement) {
648 if (configStatement != null) {
649 super.writer.startConfigNode(configStatement.rawArgument());
650 super.writer.endNode();
654 private void emitMandatoryNode(@Nullable final MandatoryStatement mandatoryStatement) {
655 if (mandatoryStatement != null) {
656 super.writer.startMandatoryNode(mandatoryStatement.rawArgument());
657 super.writer.endNode();
661 private void emitPresenceNode(@Nullable final PresenceStatement presenceStatement) {
662 if (presenceStatement != null) {
663 super.writer.startPresenceNode(presenceStatement.rawArgument());
664 super.writer.endNode();
668 private void emitOrderedBy(@Nullable final OrderedByStatement orderedByStatement) {
669 if (orderedByStatement != null) {
670 super.writer.startOrderedByNode(orderedByStatement.rawArgument());
671 super.writer.endNode();
675 private void emitMust(@Nullable final 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(@Nullable final ErrorMessageStatement errorMessageStatement) {
687 if (errorMessageStatement != null) {
688 super.writer.startErrorMessageNode(errorMessageStatement.rawArgument());
689 super.writer.endNode();
693 private void emitErrorAppTagNode(@Nullable final ErrorAppTagStatement errorAppTagStatement) {
694 if (errorAppTagStatement != null) {
695 super.writer.startErrorAppTagNode(errorAppTagStatement.rawArgument());
696 super.writer.endNode();
700 private void emitMinElementsNode(@Nullable final MinElementsStatement minElementsStatement) {
701 if (minElementsStatement != null) {
702 super.writer.startMinElementsNode(minElementsStatement.rawArgument());
703 super.writer.endNode();
707 private void emitMaxElementsNode(@Nullable final MaxElementsStatement maxElementsStatement) {
708 if (maxElementsStatement != null) {
709 super.writer.startMaxElementsNode(maxElementsStatement.rawArgument());
710 super.writer.endNode();
714 private void emitValueNode(@Nullable final 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 Preconditions.checkState(shortCaseChilds.size() == 1,
882 "Only one child is allowed for each short case node");
883 emitShortCases(shortCaseChilds);
888 private void emitCaseNode(final CaseStatement caze) {
889 super.writer.startCaseNode(caze.rawArgument());
890 emitWhen(caze.getWhenStatement());
891 emitIfFeatures(caze.getIfFeatures());
892 emitDocumentedNodeWithStatus(caze);
893 emitDataNodeContainer(caze);
894 emitUnknownStatementNodes(caze);
895 super.writer.endNode();
898 private void emitAnyxml(final AnyxmlStatement anyxml) {
899 super.writer.startAnyxmlNode(anyxml.rawArgument());
900 emitDocumentedNodeWithStatus(anyxml);
901 emitWhen(anyxml.getWhenStatement());
902 emitIfFeatures(anyxml.getIfFeatures());
903 emitMustNodes(anyxml.getMusts());
904 emitConfigNode(anyxml.getConfig());
905 emitMandatoryNode(anyxml.getMandatory());
906 emitDocumentedNodeWithStatus(anyxml);
907 emitUnknownStatementNodes(anyxml);
908 super.writer.endNode();
911 private void emitAnydata(final AnydataStatement anydata) {
912 super.writer.startAnydataNode(anydata.rawArgument());
913 emitWhen(anydata.getWhenStatement());
914 emitIfFeatures(anydata.getIfFeatures());
915 emitMustNodes(anydata.getMusts());
916 emitConfigNode(anydata.getConfig());
917 emitMandatoryNode(anydata.getMandatory());
918 emitDocumentedNodeWithStatus(anydata);
919 emitUnknownStatementNodes(anydata);
920 super.writer.endNode();
923 private void emitUsesNode(final UsesStatement uses) {
924 super.writer.startUsesNode(uses.rawArgument());
925 emitWhen(uses.getWhenStatement());
926 emitIfFeatures(uses.getIfFeatures());
927 emitDocumentedNodeWithStatus(uses);
928 for (final RefineStatement refine : uses.getRefines()) {
931 for (final AugmentStatement aug : uses.getAugments()) {
932 emitUsesAugmentNode(aug);
934 super.writer.endNode();
937 private void emitRefine(final RefineStatement refine) {
938 super.writer.startRefineNode(refine.rawArgument());
939 emitDocumentedNode(refine);
940 emitIfFeatures(refine.getIfFeatures());
941 emitMustNodes(refine.getMusts());
942 emitPresenceNode(refine.getPresence());
943 emitDefaultNodes(refine.getDefaults());
944 emitConfigNode(refine.getConfig());
945 emitMandatoryNode(refine.getMandatory());
946 emitMinElementsNode(refine.getMinElements());
947 emitMaxElementsNode(refine.getMaxElements());
948 super.writer.endNode();
951 private void emitUsesAugmentNode(final AugmentStatement aug) {
953 * differs only in location in schema, otherwise currently (as of
954 * RFC6020) it is same, so we could freely reuse path.
959 private void emitAugment(final AugmentStatement augmentation) {
960 super.writer.startAugmentNode(augmentation.rawArgument());
961 emitIfFeatures(augmentation.getIfFeatures());
962 emitWhen(augmentation.getWhenStatement());
963 emitDocumentedNodeWithStatus(augmentation);
964 emitDataNodeContainer(augmentation);
965 emitCases(augmentation.getCases());
966 emitUnknownStatementNodes(augmentation);
967 emitNotifications(augmentation.getNotifications());
968 emitActions(augmentation.getActions());
969 super.writer.endNode();
972 private void emitUnknownStatementNodes(final DeclaredStatement<?> decaredStmt) {
973 final Collection<? extends DeclaredStatement<?>> unknownStmts = Collections2
974 .filter(decaredStmt.declaredSubstatements(), Predicates.instanceOf(UnknownStatement.class));
975 for (final DeclaredStatement<?> unknonwnStmt : unknownStmts) {
976 emitUnknownStatementNode(unknonwnStmt);
980 private void emitUnknownStatementNode(final DeclaredStatement<?> unknonwnStmt) {
981 final StatementDefinition def = unknonwnStmt.statementDefinition();
982 if (def.getArgumentName() == null) {
983 super.writer.startUnknownNode(def);
985 super.writer.startUnknownNode(def, unknonwnStmt.rawArgument());
987 emitUnknownStatementNodes(unknonwnStmt);
988 super.writer.endNode();
991 private void emitWhen(final WhenStatement whenStatement) {
992 if (whenStatement != null) {
993 super.writer.startWhenNode(whenStatement.rawArgument());
994 emitDocumentedNode(whenStatement);
995 super.writer.endNode();
999 private void emitRpc(final RpcStatement rpc) {
1000 super.writer.startRpcNode(rpc.rawArgument());
1001 emitOperationBody(rpc);
1002 emitUnknownStatementNodes(rpc);
1003 super.writer.endNode();
1006 private void emitOperationBody(final OperationGroup operationStmt) {
1007 emitIfFeatures(operationStmt.getIfFeatures());
1008 emitStatusNode(operationStmt.getStatus());
1009 emitDescriptionNode(operationStmt.getDescription());
1010 emitReferenceNode(operationStmt.getReference());
1012 for (final TypedefStatement typedef : operationStmt.getTypedefs()) {
1013 emitTypedefNode(typedef);
1015 for (final GroupingStatement grouping : operationStmt.getGroupings()) {
1016 emitGrouping(grouping);
1018 emitInput(operationStmt.getInput());
1019 emitOutput(operationStmt.getOutput());
1022 private void emitActions(final Collection<? extends ActionStatement> collection) {
1023 for (final ActionStatement actionDefinition : collection) {
1024 emitAction(actionDefinition);
1028 private void emitAction(final ActionStatement actionDefinition) {
1029 super.writer.startActionNode(actionDefinition.rawArgument());
1030 emitOperationBody(actionDefinition);
1031 emitUnknownStatementNodes(actionDefinition);
1032 super.writer.endNode();
1035 private void emitInput(final InputStatement inputStatement) {
1036 if (isExplicitStatement(inputStatement)) {
1037 super.writer.startInputNode();
1038 emitMustNodes(inputStatement.getMusts());
1039 emitDataNodeContainer(inputStatement);
1040 emitUnknownStatementNodes(inputStatement);
1041 super.writer.endNode();
1045 private void emitOutput(final OutputStatement output) {
1046 if (isExplicitStatement(output)) {
1047 super.writer.startOutputNode();
1048 emitMustNodes(output.getMusts());
1049 emitDataNodeContainer(output);
1050 emitUnknownStatementNodes(output);
1051 super.writer.endNode();
1055 private static boolean isExplicitStatement(final DeclaredStatement<?> stmt) {
1056 return stmt != null && stmt.getStatementSource() == StatementSource.DECLARATION;
1059 private void emitNotifications(final Collection<? extends NotificationStatement> collection) {
1060 for (final NotificationStatement notification : collection) {
1061 emitNotificationNode(notification);
1065 private void emitNotificationNode(final NotificationStatement notification) {
1066 super.writer.startNotificationNode(notification.rawArgument());
1067 emitIfFeatures(notification.getIfFeatures());
1068 emitMustNodes(notification.getMusts());
1069 emitDocumentedNodeWithStatus(notification);
1070 emitDataNodeContainer(notification);
1071 emitUnknownStatementNodes(notification);
1072 super.writer.endNode();
1075 private void emitDeviation(final DeviationStatement deviation) {
1076 super.writer.startDeviationNode(deviation.rawArgument());
1077 emitDeviateStatements(deviation.getDeviateStatements());
1078 emitUnknownStatementNodes(deviation);
1079 super.writer.endNode();
1082 private void emitDeviateStatements(final Collection<? extends DeviateStatement> deviateStatements) {
1083 for (final DeviateStatement deviateStatement : deviateStatements) {
1084 emitDeviate(deviateStatement);
1088 private void emitDeviate(final DeviateStatement deviateStatement) {
1089 super.writer.startDeviateNode(deviateStatement.rawArgument());
1091 * :FIXME Currently, DeviateStatementImpl contains implementation
1092 * for all deviate types (i.e. add, replace, delete). However it
1093 * would be better to create subinterfaces of DeviateStatement for
1094 * each deviate type (i.e. AddDeviateStatement,
1095 * ReplaceDeviateStatement,..) and create argument specific supports
1096 * (i.e. definitions) for each deviate type (very similarly like by
1099 for (final DeclaredStatement<?> child : deviateStatement.declaredSubstatements()) {
1100 if (child instanceof MustStatement) {
1101 emitMust((MustStatement) child);
1102 } else if (child instanceof DefaultStatement) {
1103 emitDefaultNode((DefaultStatement) child);
1104 } else if (child instanceof UniqueStatement) {
1105 emitUnique((UniqueStatement) child);
1106 } else if (child instanceof UnitsStatement) {
1107 emitUnitsNode((UnitsStatement) child);
1108 } else if (child instanceof TypeStatement) {
1109 emitType((TypeStatement) child);
1110 } else if (child instanceof MinElementsStatement) {
1111 emitMinElementsNode((MinElementsStatement) child);
1112 } else if (child instanceof MaxElementsStatement) {
1113 emitMaxElementsNode((MaxElementsStatement) child);
1114 } else if (child instanceof MandatoryStatement) {
1115 emitMandatoryNode((MandatoryStatement) child);
1116 } else if (child instanceof ConfigStatement) {
1117 emitConfigNode((ConfigStatement) child);
1118 } else if (child instanceof UnknownStatement) {
1119 emitUnknownStatementNode(child);
1122 super.writer.endNode();
1126 static class EffectiveSchemaContextEmitter extends SchemaContextEmitter {
1128 EffectiveSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
1129 final YangVersion yangVersion, final boolean emitInstantiated) {
1130 super(writer, extensions, yangVersion, emitInstantiated, true);
1133 void emitModule(final Module input) {
1134 super.writer.startModuleNode(input.getName());
1135 emitModuleHeader(input);
1136 emitLinkageNodes(input);
1137 emitMetaNodes(input);
1138 emitRevisionNodes(input);
1139 emitBodyNodes(input);
1140 super.writer.endNode();
1143 private void emitModuleHeader(final Module input) {
1144 emitYangVersionNode(input.getYangVersion());
1145 emitNamespace(input.getNamespace());
1146 emitPrefixNode(input.getPrefix());
1149 @SuppressWarnings("unused")
1150 private void emitSubmodule(final String input) {
1152 * FIXME: BUG-2444: Implement submodule export
1154 * submoduleHeaderNodes linkageNodes metaNodes revisionNodes
1155 * bodyNodes super.writer.endNode();
1159 @SuppressWarnings("unused")
1160 private void emitSubmoduleHeaderNodes(final Module input) {
1162 * FIXME: BUG-2444: Implement submodule headers properly
1164 * :yangVersionNode //Optional
1170 private void emitMetaNodes(final Module input) {
1171 input.getOrganization().ifPresent(this::emitOrganizationNode);
1172 input.getContact().ifPresent(this::emitContact);
1173 emitDocumentedNode(input);
1176 private void emitLinkageNodes(final Module input) {
1177 for (final ModuleImport importNode : input.getImports()) {
1178 emitImport(importNode);
1181 * FIXME: BUG-2444: Emit include statements
1185 private void emitRevisionNodes(final Module input) {
1187 * FIXME: BUG-2444: emit revisions properly, when parsed model will
1188 * provide enough information
1190 input.getRevision().ifPresent(this::emitRevision);
1193 private void emitBodyNodes(final Module input) {
1195 for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
1196 emitExtension(extension);
1198 for (final FeatureDefinition definition : input.getFeatures()) {
1199 emitFeature(definition);
1201 for (final IdentitySchemaNode identity : input.getIdentities()) {
1202 emitIdentity(identity);
1204 for (final Deviation deviation : input.getDeviations()) {
1205 emitDeviation(deviation);
1208 emitDataNodeContainer(input);
1210 for (final AugmentationSchemaNode augmentation : input.getAugmentations()) {
1211 emitAugment(augmentation);
1213 for (final RpcDefinition rpc : input.getRpcs()) {
1217 emitNotifications(input.getNotifications());
1220 private void emitDataNodeContainer(final DataNodeContainer input) {
1221 for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
1222 emitTypedefNode(typedef);
1224 for (final GroupingDefinition grouping : input.getGroupings()) {
1225 emitGrouping(grouping);
1227 for (final DataSchemaNode child : input.getChildNodes()) {
1228 emitDataSchemaNode(child);
1230 for (final UsesNode usesNode : input.getUses()) {
1231 emitUsesNode(usesNode);
1235 private void emitDataSchemaNode(final DataSchemaNode child) {
1236 if (!super.emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
1237 // We skip instantiated nodes.
1241 if (child instanceof ContainerSchemaNode) {
1242 emitContainer((ContainerSchemaNode) child);
1243 } else if (child instanceof LeafSchemaNode) {
1244 emitLeaf((LeafSchemaNode) child);
1245 } else if (child instanceof LeafListSchemaNode) {
1246 emitLeafList((LeafListSchemaNode) child);
1247 } else if (child instanceof ListSchemaNode) {
1248 emitList((ListSchemaNode) child);
1249 } else if (child instanceof ChoiceSchemaNode) {
1250 emitChoice((ChoiceSchemaNode) child);
1251 } else if (child instanceof AnyXmlSchemaNode) {
1252 emitAnyxml((AnyXmlSchemaNode) child);
1253 } else if (child instanceof AnyDataSchemaNode) {
1254 emitAnydata((AnyDataSchemaNode) child);
1256 throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
1260 private void emitYangVersionNode(final YangVersion input) {
1261 super.writer.startYangVersionNode(input.toString());
1262 super.writer.endNode();
1265 private void emitImport(final ModuleImport importNode) {
1266 super.writer.startImportNode(importNode.getModuleName());
1267 emitDocumentedNode(importNode);
1268 emitPrefixNode(importNode.getPrefix());
1269 importNode.getRevision().ifPresent(this::emitRevisionDateNode);
1270 super.writer.endNode();
1273 @SuppressWarnings("unused")
1274 private void emitInclude(final String input) {
1276 * FIXME: BUG-2444: Implement proper export of include statements
1277 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1280 * :revisionDateNode :super.writer.endNode();)
1284 private void emitNamespace(final URI uri) {
1285 super.writer.startNamespaceNode(uri);
1286 super.writer.endNode();
1290 private void emitPrefixNode(final String input) {
1291 super.writer.startPrefixNode(input);
1292 super.writer.endNode();
1296 @SuppressWarnings("unused")
1297 private void emitBelongsTo(final String input) {
1299 * FIXME: BUG-2444: Implement proper export of belongs-to statements
1300 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1303 * :super.writer.startBelongsToNode(IdentifierHelper.getIdentifier(
1307 * :prefixNode :super.writer.endNode();
1313 private void emitOrganizationNode(final String input) {
1314 super.writer.startOrganizationNode(input);
1315 super.writer.endNode();
1318 private void emitContact(final String input) {
1319 super.writer.startContactNode(input);
1320 super.writer.endNode();
1323 private void emitDescriptionNode(final String input) {
1324 super.writer.startDescriptionNode(input);
1325 super.writer.endNode();
1328 private void emitReferenceNode(final String input) {
1329 super.writer.startReferenceNode(input);
1330 super.writer.endNode();
1333 private void emitUnitsNode(@Nullable final String input) {
1334 super.writer.startUnitsNode(input);
1335 super.writer.endNode();
1338 private void emitRevision(final Revision date) {
1340 super.writer.startRevisionNode(date);
1342 // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode
1343 // //FIXME: BUG-2444: Optional
1344 // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode
1345 // //FIXME: BUG-2444: Optional
1346 super.writer.endNode();
1350 private void emitRevisionDateNode(final Revision date) {
1351 super.writer.startRevisionDateNode(date);
1352 super.writer.endNode();
1355 private void emitExtension(final ExtensionDefinition extension) {
1356 super.writer.startExtensionNode(extension.getQName());
1357 emitArgument(extension.getArgument(), extension.isYinElement());
1358 emitDocumentedNode(extension);
1359 emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
1360 super.writer.endNode();
1364 private void emitArgument(final @Nullable String input, final boolean yinElement) {
1365 if (input != null) {
1366 super.writer.startArgumentNode(input);
1367 emitYinElement(yinElement);
1368 super.writer.endNode();
1373 private void emitYinElement(final boolean yinElement) {
1374 super.writer.startYinElementNode(yinElement);
1375 super.writer.endNode();
1379 private void emitIdentity(final IdentitySchemaNode identity) {
1380 super.writer.startIdentityNode(identity.getQName());
1381 emitBaseIdentities(identity.getBaseIdentities());
1382 emitDocumentedNode(identity);
1383 super.writer.endNode();
1386 private void emitBaseIdentities(final Set<IdentitySchemaNode> identities) {
1387 for (final IdentitySchemaNode identitySchemaNode : identities) {
1388 emitBase(identitySchemaNode.getQName());
1392 private void emitBase(final QName qName) {
1393 super.writer.startBaseNode(qName);
1394 super.writer.endNode();
1397 private void emitFeature(final FeatureDefinition definition) {
1398 super.writer.startFeatureNode(definition.getQName());
1400 // FIXME: BUG-2444: FIXME: BUG-2444: Expose ifFeature
1401 // *(ifFeatureNode )
1402 emitDocumentedNode(definition);
1403 super.writer.endNode();
1406 @SuppressWarnings("unused")
1407 private void emitIfFeature(final String input) {
1409 * FIXME: BUG-2444: Implement proper export of include statements
1410 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1415 private void emitTypedefNode(final TypeDefinition<?> typedef) {
1416 super.writer.startTypedefNode(typedef.getQName());
1417 // Differentiate between derived type and existing type
1419 emitTypeNodeDerived(typedef);
1420 typedef.getUnits().ifPresent(this::emitUnitsNode);
1421 typedef.getDefaultValue().ifPresent(this::emitDefaultNode);
1422 emitDocumentedNode(typedef);
1423 emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
1424 super.writer.endNode();
1427 private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
1428 final SchemaPath path = subtype.getPath();
1429 if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
1430 emitTypeNodeDerived(subtype);
1432 emitTypeNodeReferenced(subtype);
1436 private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
1437 super.writer.startTypeNode(typeDefinition.getQName());
1438 super.writer.endNode();
1442 private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
1443 final TypeDefinition<?> b = typeDefinition.getBaseType();
1444 final TypeDefinition<?> baseType = b == null ? typeDefinition : b;
1445 super.writer.startTypeNode(baseType.getQName());
1446 emitTypeBodyNodes(typeDefinition);
1447 super.writer.endNode();
1451 private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
1452 if (typeDef instanceof UnsignedIntegerTypeDefinition) {
1453 emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
1454 } else if (typeDef instanceof IntegerTypeDefinition) {
1455 emitIntegerSpefication((IntegerTypeDefinition) typeDef);
1456 } else if (typeDef instanceof DecimalTypeDefinition) {
1457 emitDecimal64Specification((DecimalTypeDefinition) typeDef);
1458 } else if (typeDef instanceof StringTypeDefinition) {
1459 emitStringRestrictions((StringTypeDefinition) typeDef);
1460 } else if (typeDef instanceof EnumTypeDefinition) {
1461 emitEnumSpecification((EnumTypeDefinition) typeDef);
1462 } else if (typeDef instanceof LeafrefTypeDefinition) {
1463 emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
1464 } else if (typeDef instanceof IdentityrefTypeDefinition) {
1465 emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
1466 } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
1467 emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
1468 } else if (typeDef instanceof BitsTypeDefinition) {
1469 emitBitsSpecification((BitsTypeDefinition) typeDef);
1470 } else if (typeDef instanceof UnionTypeDefinition) {
1471 emitUnionSpecification((UnionTypeDefinition) typeDef);
1472 } else if (typeDef instanceof BinaryTypeDefinition) {
1473 ((BinaryTypeDefinition) typeDef).getLengthConstraint().ifPresent(this::emitLength);
1474 } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
1477 throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
1481 private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
1482 typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
1485 private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
1486 typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
1489 private void emitRangeNode(final RangeConstraint<?> constraint) {
1490 super.writer.startRangeNode(toRangeString(constraint.getAllowedRanges()));
1491 constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1492 constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1493 emitDocumentedNode(constraint);
1494 super.writer.endNode();
1497 private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
1498 emitFranctionDigitsNode(typeDefinition.getFractionDigits());
1499 typeDefinition.getRangeConstraint().ifPresent(this::emitRangeNode);
1502 private void emitFranctionDigitsNode(final Integer fractionDigits) {
1503 super.writer.startFractionDigitsNode(fractionDigits);
1504 super.writer.endNode();
1507 private void emitStringRestrictions(final StringTypeDefinition typeDef) {
1508 typeDef.getLengthConstraint().ifPresent(this::emitLength);
1510 for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
1511 emitPatternNode(pattern);
1515 private void emitLength(final LengthConstraint constraint) {
1516 super.writer.startLengthNode(toLengthString(constraint.getAllowedRanges()));
1517 constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1518 constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1519 emitDocumentedNode(constraint);
1520 super.writer.endNode();
1523 private static String toLengthString(final RangeSet<Integer> ranges) {
1524 final Iterator<Range<Integer>> it = ranges.asRanges().iterator();
1525 if (!it.hasNext()) {
1529 final StringBuilder sb = new StringBuilder();
1532 final Range<Integer> current = it.next();
1533 haveNext = it.hasNext();
1534 appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
1537 return sb.toString();
1540 private static String toRangeString(final RangeSet<?> ranges) {
1541 final Iterator<? extends Range<?>> it = ranges.asRanges().iterator();
1542 if (!it.hasNext()) {
1546 final StringBuilder sb = new StringBuilder();
1549 final Range<?> current = it.next();
1550 haveNext = it.hasNext();
1551 appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
1554 return sb.toString();
1557 private static void appendRange(final StringBuilder sb, final Object min, final Object max,
1558 final boolean haveNext) {
1560 if (!min.equals(max)) {
1569 private void emitPatternNode(final PatternConstraint pattern) {
1570 super.writer.startPatternNode(pattern.getRegularExpressionString());
1571 pattern.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1572 pattern.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1573 emitDocumentedNode(pattern);
1574 pattern.getModifier().ifPresent(this::emitModifier);
1575 super.writer.endNode();
1578 private void emitModifier(final ModifierKind modifier) {
1579 super.writer.startModifierNode(modifier);
1580 super.writer.endNode();
1583 private void emitDefaultNodes(final Collection<String> defaults) {
1584 for (final String defaultValue : defaults) {
1585 emitDefaultNode(defaultValue);
1589 private void emitDefaultNode(@Nullable final Object object) {
1590 super.writer.startDefaultNode(object.toString());
1591 super.writer.endNode();
1594 private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
1595 for (final EnumPair enumValue : typeDefinition.getValues()) {
1596 emitEnumNode(enumValue);
1600 private void emitEnumNode(final EnumPair enumValue) {
1601 super.writer.startEnumNode(enumValue.getName());
1602 emitValueNode(enumValue.getValue());
1603 emitDocumentedNode(enumValue);
1604 super.writer.endNode();
1607 private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
1608 emitPathNode(typeDefinition.getPathStatement());
1609 if (YangVersion.VERSION_1_1 == super.yangVersion) {
1610 emitRequireInstanceNode(typeDefinition.requireInstance());
1614 private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
1615 super.writer.startPathNode(revisionAwareXPath);
1616 super.writer.endNode();
1619 private void emitRequireInstanceNode(final boolean require) {
1620 super.writer.startRequireInstanceNode(require);
1621 super.writer.endNode();
1624 private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
1625 emitRequireInstanceNode(typeDefinition.requireInstance());
1628 private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
1629 emitBaseIdentities(typeDefinition.getIdentities());
1632 private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
1633 for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
1634 // FIXME: BUG-2444: What if we have locally modified types here?
1635 // is solution to look-up in schema path?
1636 emitTypeNode(typeDefinition.getPath(), subtype);
1640 private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
1641 for (final Bit bit : typeDefinition.getBits()) {
1646 private void emitBit(final Bit bit) {
1647 super.writer.startBitNode(bit.getName());
1648 emitPositionNode(bit.getPosition());
1649 emitDocumentedNode(bit);
1650 super.writer.endNode();
1653 private void emitPositionNode(@Nullable final Long position) {
1654 if (position != null) {
1655 super.writer.startPositionNode(UnsignedInteger.valueOf(position));
1656 super.writer.endNode();
1660 private void emitStatusNode(@Nullable final Status status) {
1661 if (status != null) {
1662 super.writer.startStatusNode(status);
1663 super.writer.endNode();
1667 private void emitConfigNode(final boolean config) {
1668 super.writer.startConfigNode(config);
1669 super.writer.endNode();
1672 private void emitMandatoryNode(final boolean mandatory) {
1673 super.writer.startMandatoryNode(mandatory);
1674 super.writer.endNode();
1677 private void emitPresenceNode(final boolean presence) {
1678 super.writer.startPresenceNode(presence);
1679 super.writer.endNode();
1682 private void emitOrderedBy(final boolean userOrdered) {
1684 super.writer.startOrderedByNode("user");
1686 super.writer.startOrderedByNode("system");
1688 super.writer.endNode();
1691 private void emitMust(@Nullable final MustDefinition mustCondition) {
1692 if (mustCondition != null && mustCondition.getXpath() != null) {
1693 super.writer.startMustNode(mustCondition.getXpath());
1694 mustCondition.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1695 mustCondition.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1696 emitDocumentedNode(mustCondition);
1697 super.writer.endNode();
1701 private void emitErrorMessageNode(@Nullable final String input) {
1702 super.writer.startErrorMessageNode(input);
1703 super.writer.endNode();
1706 private void emitErrorAppTagNode(final String input) {
1707 super.writer.startErrorAppTagNode(input);
1708 super.writer.endNode();
1711 private void emitMinElementsNode(final Integer min) {
1713 super.writer.startMinElementsNode(min);
1714 super.writer.endNode();
1718 private void emitMaxElementsNode(final Integer max) {
1720 super.writer.startMaxElementsNode(max);
1721 super.writer.endNode();
1725 private void emitValueNode(@Nullable final Integer value) {
1726 if (value != null) {
1727 super.writer.startValueNode(value);
1728 super.writer.endNode();
1732 private void emitDocumentedNode(final DocumentedNode input) {
1733 input.getDescription().ifPresent(this::emitDescriptionNode);
1734 input.getReference().ifPresent(this::emitReferenceNode);
1737 private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
1738 emitStatusNode(input.getStatus());
1739 emitDocumentedNode((DocumentedNode) input);
1742 private void emitGrouping(final GroupingDefinition grouping) {
1743 super.writer.startGroupingNode(grouping.getQName());
1744 emitDocumentedNode(grouping);
1745 emitDataNodeContainer(grouping);
1746 emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
1747 emitNotifications(grouping.getNotifications());
1748 emitActions(grouping.getActions());
1749 super.writer.endNode();
1753 private void emitContainer(final ContainerSchemaNode child) {
1754 super.writer.startContainerNode(child.getQName());
1755 emitConstraints(child.getConstraints());
1756 // FIXME: BUG-2444: whenNode //:Optional
1757 // FIXME: BUG-2444: *(ifFeatureNode )
1758 emitPresenceNode(child.isPresenceContainer());
1759 emitConfigNode(child.isConfiguration());
1760 emitDocumentedNode(child);
1761 emitDataNodeContainer(child);
1762 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1763 emitNotifications(child.getNotifications());
1764 emitActions(child.getActions());
1765 super.writer.endNode();
1769 private void emitConstraints(final ConstraintDefinition constraints) {
1770 constraints.getWhenCondition().ifPresent(this::emitWhen);
1771 for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
1772 emitMust(mustCondition);
1776 private void emitLeaf(final LeafSchemaNode child) {
1777 super.writer.startLeafNode(child.getQName());
1778 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1779 // FIXME: BUG-2444: *(ifFeatureNode )
1780 emitTypeNode(child.getPath(), child.getType());
1781 child.getType().getUnits().ifPresent(this::emitUnitsNode);
1782 emitMustNodes(child.getConstraints().getMustConstraints());
1783 child.getType().getDefaultValue().ifPresent(this::emitDefaultNode);
1784 emitConfigNode(child.isConfiguration());
1785 emitMandatoryNode(child.getConstraints().isMandatory());
1786 emitDocumentedNode(child);
1787 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1788 super.writer.endNode();
1792 private void emitLeafList(final LeafListSchemaNode child) {
1793 super.writer.startLeafListNode(child.getQName());
1795 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1796 // FIXME: BUG-2444: *(ifFeatureNode )
1797 emitTypeNode(child.getPath(), child.getType());
1798 child.getType().getUnits().ifPresent(this::emitUnitsNode);
1799 // FIXME: BUG-2444: unitsNode /Optional
1800 emitMustNodes(child.getConstraints().getMustConstraints());
1801 emitConfigNode(child.isConfiguration());
1802 emitDefaultNodes(child.getDefaults());
1803 emitMinElementsNode(child.getConstraints().getMinElements());
1804 emitMaxElementsNode(child.getConstraints().getMaxElements());
1805 emitOrderedBy(child.isUserOrdered());
1806 emitDocumentedNode(child);
1807 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1808 super.writer.endNode();
1812 private void emitList(final ListSchemaNode child) {
1813 super.writer.startListNode(child.getQName());
1814 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1816 // FIXME: BUG-2444: *(ifFeatureNode )
1817 emitMustNodes(child.getConstraints().getMustConstraints());
1818 emitKey(child.getKeyDefinition());
1819 emitUniqueConstraints(child.getUniqueConstraints());
1820 emitConfigNode(child.isConfiguration());
1821 emitMinElementsNode(child.getConstraints().getMinElements());
1822 emitMaxElementsNode(child.getConstraints().getMaxElements());
1823 emitOrderedBy(child.isUserOrdered());
1824 emitDocumentedNode(child);
1825 emitDataNodeContainer(child);
1826 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1827 emitNotifications(child.getNotifications());
1828 emitActions(child.getActions());
1829 super.writer.endNode();
1833 private void emitMustNodes(final Collection<MustDefinition> mustConstraints) {
1834 for (final MustDefinition must : mustConstraints) {
1839 private void emitKey(final List<QName> keyList) {
1840 if (keyList != null && !keyList.isEmpty()) {
1841 super.writer.startKeyNode(keyList);
1842 super.writer.endNode();
1846 private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
1847 for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
1848 emitUnique(uniqueConstraint);
1852 private void emitUnique(final UniqueConstraint uniqueConstraint) {
1853 super.writer.startUniqueNode(uniqueConstraint);
1854 super.writer.endNode();
1857 private void emitChoice(final ChoiceSchemaNode choice) {
1858 super.writer.startChoiceNode(choice.getQName());
1859 choice.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1860 // FIXME: BUG-2444: *(ifFeatureNode )
1861 // FIXME: BUG-2444: defaultNode //Optional
1862 emitConfigNode(choice.isConfiguration());
1863 emitMandatoryNode(choice.getConstraints().isMandatory());
1864 emitDocumentedNode(choice);
1865 for (final ChoiceCaseNode caze : choice.getCases().values()) {
1866 // TODO: emit short case?
1869 emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
1870 super.writer.endNode();
1873 private void emitCaseNode(final ChoiceCaseNode caze) {
1874 if (!super.emitInstantiated && caze.isAugmenting()) {
1877 super.writer.startCaseNode(caze.getQName());
1878 caze.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1879 // FIXME: BUG-2444: *(ifFeatureNode )
1880 emitDocumentedNode(caze);
1881 emitDataNodeContainer(caze);
1882 emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
1883 super.writer.endNode();
1887 private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
1888 super.writer.startAnyxmlNode(anyxml.getQName());
1889 emitBodyOfDataSchemaNode(anyxml);
1890 super.writer.endNode();
1893 private void emitAnydata(final AnyDataSchemaNode anydata) {
1894 super.writer.startAnydataNode(anydata.getQName());
1895 emitBodyOfDataSchemaNode(anydata);
1896 super.writer.endNode();
1899 private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
1900 dataSchemaNode.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1901 // FIXME: BUG-2444: *(ifFeatureNode )
1902 emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
1903 emitConfigNode(dataSchemaNode.isConfiguration());
1904 emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
1905 emitDocumentedNode(dataSchemaNode);
1906 emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
1909 private void emitUsesNode(final UsesNode usesNode) {
1910 if (super.emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
1911 super.writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
1913 * FIXME: BUG-2444: whenNode / *(ifFeatureNode ) statusNode //
1914 * Optional F : descriptionNode // Optional referenceNode //
1917 for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
1920 for (final AugmentationSchemaNode aug : usesNode.getAugmentations()) {
1921 emitUsesAugmentNode(aug);
1923 super.writer.endNode();
1927 private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
1928 final SchemaPath path = refine.getKey();
1929 final SchemaNode value = refine.getValue();
1930 super.writer.startRefineNode(path);
1932 if (value instanceof LeafSchemaNode) {
1933 emitRefineLeafNodes((LeafSchemaNode) value);
1934 } else if (value instanceof LeafListSchemaNode) {
1935 emitRefineLeafListNodes((LeafListSchemaNode) value);
1936 } else if (value instanceof ListSchemaNode) {
1937 emitRefineListNodes((ListSchemaNode) value);
1938 } else if (value instanceof ChoiceSchemaNode) {
1939 emitRefineChoiceNodes((ChoiceSchemaNode) value);
1940 } else if (value instanceof ChoiceCaseNode) {
1941 emitRefineCaseNodes((ChoiceCaseNode) value);
1942 } else if (value instanceof ContainerSchemaNode) {
1943 emitRefineContainerNodes((ContainerSchemaNode) value);
1944 } else if (value instanceof AnyXmlSchemaNode) {
1945 emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
1947 super.writer.endNode();
1951 private static <T extends SchemaNode> T getOriginalChecked(final T value) {
1952 final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
1953 Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
1954 @SuppressWarnings("unchecked")
1955 final T ret = (T) original.get();
1959 private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
1960 if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
1961 value.getDescription().ifPresent(this::emitDescriptionNode);
1963 if (Objects.deepEquals(original.getReference(), value.getReference())) {
1964 value.getReference().ifPresent(this::emitReferenceNode);
1968 private void emitRefineContainerNodes(final ContainerSchemaNode value) {
1969 final ContainerSchemaNode original = getOriginalChecked(value);
1971 // emitMustNodes(child.getConstraints().getMustConstraints());
1972 if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
1973 emitPresenceNode(value.isPresenceContainer());
1975 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1976 emitConfigNode(value.isConfiguration());
1978 emitDocumentedNodeRefine(original, value);
1982 private void emitRefineLeafNodes(final LeafSchemaNode value) {
1983 final LeafSchemaNode original = getOriginalChecked(value);
1985 // emitMustNodes(child.getConstraints().getMustConstraints());
1986 if (Objects.deepEquals(original.getType().getDefaultValue(), value.getType().getDefaultValue())) {
1987 emitDefaultNode(value.getType().getDefaultValue());
1989 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1990 emitConfigNode(value.isConfiguration());
1992 emitDocumentedNodeRefine(original, value);
1993 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
1994 emitMandatoryNode(value.getConstraints().isMandatory());
1999 private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
2000 final LeafListSchemaNode original = getOriginalChecked(value);
2002 // emitMustNodes(child.getConstraints().getMustConstraints());
2003 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2004 emitConfigNode(value.isConfiguration());
2006 if (Objects.deepEquals(original.getConstraints().getMinElements(),
2007 value.getConstraints().getMinElements())) {
2008 emitMinElementsNode(value.getConstraints().getMinElements());
2010 if (Objects.deepEquals(original.getConstraints().getMaxElements(),
2011 value.getConstraints().getMaxElements())) {
2012 emitMaxElementsNode(value.getConstraints().getMaxElements());
2014 emitDocumentedNodeRefine(original, value);
2018 private void emitRefineListNodes(final ListSchemaNode value) {
2019 final ListSchemaNode original = getOriginalChecked(value);
2021 // emitMustNodes(child.getConstraints().getMustConstraints());
2022 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2023 emitConfigNode(value.isConfiguration());
2025 if (Objects.deepEquals(original.getConstraints().getMinElements(),
2026 value.getConstraints().getMinElements())) {
2027 emitMinElementsNode(value.getConstraints().getMinElements());
2029 if (Objects.deepEquals(original.getConstraints().getMaxElements(),
2030 value.getConstraints().getMaxElements())) {
2031 emitMaxElementsNode(value.getConstraints().getMaxElements());
2033 emitDocumentedNodeRefine(original, value);
2037 private void emitRefineChoiceNodes(final ChoiceSchemaNode value) {
2038 final ChoiceSchemaNode original = getOriginalChecked(value);
2040 // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
2041 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2042 emitConfigNode(value.isConfiguration());
2044 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2045 emitMandatoryNode(value.getConstraints().isMandatory());
2047 emitDocumentedNodeRefine(original, value);
2051 private void emitRefineCaseNodes(final ChoiceCaseNode value) {
2052 final ChoiceCaseNode original = getOriginalChecked(value);
2053 emitDocumentedNodeRefine(original, value);
2057 private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
2058 final AnyXmlSchemaNode original = getOriginalChecked(value);
2061 // emitMustNodes(child.getConstraints().getMustConstraints());
2062 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2063 emitConfigNode(value.isConfiguration());
2065 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2066 emitMandatoryNode(value.getConstraints().isMandatory());
2068 emitDocumentedNodeRefine(original, value);
2072 private void emitUsesAugmentNode(final AugmentationSchemaNode aug) {
2074 * differs only in location in schema, otherwise currently (as of
2075 * RFC6020) it is same, so we could freely reuse path.
2080 private void emitAugment(final AugmentationSchemaNode augmentation) {
2081 super.writer.startAugmentNode(augmentation.getTargetPath());
2082 // FIXME: BUG-2444: whenNode //Optional
2083 // FIXME: BUG-2444: *(ifFeatureNode )
2085 emitDocumentedNode(augmentation);
2086 for (final UsesNode uses : augmentation.getUses()) {
2090 for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
2091 if (childNode instanceof ChoiceCaseNode) {
2092 emitCaseNode((ChoiceCaseNode) childNode);
2094 emitDataSchemaNode(childNode);
2097 emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
2098 emitNotifications(augmentation.getNotifications());
2099 emitActions(augmentation.getActions());
2100 super.writer.endNode();
2103 private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
2104 for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
2105 if (!unknonwnNode.isAddedByAugmentation() && !unknonwnNode.isAddedByUses()) {
2106 emitUnknownStatementNode(unknonwnNode);
2111 private void emitUnknownStatementNode(final UnknownSchemaNode node) {
2112 final StatementDefinition def = getStatementChecked(node.getNodeType());
2113 if (def.getArgumentName() == null) {
2114 super.writer.startUnknownNode(def);
2116 super.writer.startUnknownNode(def, node.getNodeParameter());
2118 emitUnknownStatementNodes(node.getUnknownSchemaNodes());
2119 super.writer.endNode();
2122 private StatementDefinition getStatementChecked(final QName nodeType) {
2123 final StatementDefinition ret = super.extensions.get(nodeType);
2124 Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
2128 private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
2129 if (revisionAwareXPath != null) {
2130 super.writer.startWhenNode(revisionAwareXPath);
2131 super.writer.endNode();
2133 // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
2134 // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
2135 // FIXME: BUG-2444: super.writer.endNode();)
2139 private void emitRpc(final RpcDefinition rpc) {
2140 super.writer.startRpcNode(rpc.getQName());
2141 emitOperationBody(rpc);
2142 super.writer.endNode();
2145 private void emitOperationBody(final OperationDefinition rpc) {
2146 // FIXME: BUG-2444: *(ifFeatureNode )
2147 emitDocumentedNode(rpc);
2149 for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
2150 emitTypedefNode(typedef);
2152 for (final GroupingDefinition grouping : rpc.getGroupings()) {
2153 emitGrouping(grouping);
2155 emitInput(rpc.getInput());
2156 emitOutput(rpc.getOutput());
2157 emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
2160 private void emitActions(final Set<ActionDefinition> actions) {
2161 for (final ActionDefinition actionDefinition : actions) {
2162 emitAction(actionDefinition);
2166 private void emitAction(final ActionDefinition action) {
2167 if (!super.emitInstantiated && (action.isAddedByUses() || action.isAugmenting())) {
2168 // We skip instantiated nodes.
2171 super.writer.startActionNode(action.getQName());
2172 emitOperationBody(action);
2173 super.writer.endNode();
2176 private void emitInput(@Nonnull final ContainerSchemaNode input) {
2177 if (isExplicitStatement(input)) {
2178 super.writer.startInputNode();
2179 emitConstraints(input.getConstraints());
2180 emitDataNodeContainer(input);
2181 emitUnknownStatementNodes(input.getUnknownSchemaNodes());
2182 super.writer.endNode();
2187 private void emitOutput(@Nonnull final ContainerSchemaNode output) {
2188 if (isExplicitStatement(output)) {
2189 super.writer.startOutputNode();
2190 emitConstraints(output.getConstraints());
2191 emitDataNodeContainer(output);
2192 emitUnknownStatementNodes(output.getUnknownSchemaNodes());
2193 super.writer.endNode();
2197 private static boolean isExplicitStatement(final ContainerSchemaNode node) {
2198 return node instanceof EffectiveStatement && ((EffectiveStatement<?, ?>) node).getDeclared()
2199 .getStatementSource() == StatementSource.DECLARATION;
2202 private void emitNotifications(final Set<NotificationDefinition> notifications) {
2203 for (final NotificationDefinition notification : notifications) {
2204 emitNotificationNode(notification);
2208 private void emitNotificationNode(final NotificationDefinition notification) {
2209 if (!super.emitInstantiated && (notification.isAddedByUses() || notification.isAugmenting())) {
2210 // We skip instantiated nodes.
2214 super.writer.startNotificationNode(notification.getQName());
2215 // FIXME: BUG-2444: *(ifFeatureNode )
2216 for (final MustDefinition mustCondition : notification.getMustConstraints()) {
2217 emitMust(mustCondition);
2219 emitDocumentedNode(notification);
2220 emitDataNodeContainer(notification);
2221 emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
2222 super.writer.endNode();
2226 private void emitDeviation(final Deviation deviation) {
2228 * FIXME: BUG-2444: Deviation is not modeled properly and we are
2229 * loosing lot of information in order to export it properly
2231 * super.writer.startDeviationNode(deviation.getTargetPath());
2233 * :descriptionNode //:Optional
2236 * emitReferenceNode(deviation.getReference());
2237 * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
2238 * :deviateDeleteNode)) :super.writer.endNode();