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 emitRangeNodeOptional(typeDef.getRangeConstraints());
1485 private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
1486 emitRangeNodeOptional(typeDef.getRangeConstraints());
1490 private void emitRangeNodeOptional(final List<RangeConstraint> list) {
1491 // FIXME: BUG-2444: Wrong decomposition in API, should be
1493 // which contains ranges.
1494 if (!list.isEmpty()) {
1495 super.writer.startRangeNode(toRangeString(list));
1496 final RangeConstraint first = list.iterator().next();
1497 first.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1498 first.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1499 emitDocumentedNode(first);
1500 super.writer.endNode();
1505 private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
1506 emitFranctionDigitsNode(typeDefinition.getFractionDigits());
1507 emitRangeNodeOptional(typeDefinition.getRangeConstraints());
1510 private void emitFranctionDigitsNode(final Integer fractionDigits) {
1511 super.writer.startFractionDigitsNode(fractionDigits);
1512 super.writer.endNode();
1515 private void emitStringRestrictions(final StringTypeDefinition typeDef) {
1516 typeDef.getLengthConstraint().ifPresent(this::emitLength);
1518 for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
1519 emitPatternNode(pattern);
1523 private void emitLength(final LengthConstraint constraint) {
1524 super.writer.startLengthNode(toLengthString(constraint.getAllowedRanges()));
1525 constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1526 constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1527 emitDocumentedNode(constraint);
1528 super.writer.endNode();
1531 private static String toLengthString(final RangeSet<Integer> ranges) {
1532 final Iterator<Range<Integer>> it = ranges.asRanges().iterator();
1533 if (!it.hasNext()) {
1537 final StringBuilder sb = new StringBuilder();
1540 final Range<Integer> current = it.next();
1541 haveNext = it.hasNext();
1542 appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
1545 return sb.toString();
1548 private static String toRangeString(final List<RangeConstraint> list) {
1549 final Iterator<RangeConstraint> it = list.iterator();
1550 if (!it.hasNext()) {
1554 final StringBuilder sb = new StringBuilder();
1557 final RangeConstraint current = it.next();
1558 haveNext = it.hasNext();
1559 appendRange(sb, current.getMin(), current.getMax(), haveNext);
1562 return sb.toString();
1565 private static void appendRange(final StringBuilder sb, final Number min, final Number max,
1566 final boolean haveNext) {
1568 if (!min.equals(max)) {
1577 private void emitPatternNode(final PatternConstraint pattern) {
1578 super.writer.startPatternNode(pattern.getRegularExpressionString());
1579 pattern.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1580 pattern.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1581 emitDocumentedNode(pattern);
1582 pattern.getModifier().ifPresent(this::emitModifier);
1583 super.writer.endNode();
1586 private void emitModifier(final ModifierKind modifier) {
1587 super.writer.startModifierNode(modifier);
1588 super.writer.endNode();
1591 private void emitDefaultNodes(final Collection<String> defaults) {
1592 for (final String defaultValue : defaults) {
1593 emitDefaultNode(defaultValue);
1597 private void emitDefaultNode(@Nullable final Object object) {
1598 super.writer.startDefaultNode(object.toString());
1599 super.writer.endNode();
1602 private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
1603 for (final EnumPair enumValue : typeDefinition.getValues()) {
1604 emitEnumNode(enumValue);
1608 private void emitEnumNode(final EnumPair enumValue) {
1609 super.writer.startEnumNode(enumValue.getName());
1610 emitValueNode(enumValue.getValue());
1611 emitDocumentedNode(enumValue);
1612 super.writer.endNode();
1615 private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
1616 emitPathNode(typeDefinition.getPathStatement());
1617 if (YangVersion.VERSION_1_1 == super.yangVersion) {
1618 emitRequireInstanceNode(typeDefinition.requireInstance());
1622 private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
1623 super.writer.startPathNode(revisionAwareXPath);
1624 super.writer.endNode();
1627 private void emitRequireInstanceNode(final boolean require) {
1628 super.writer.startRequireInstanceNode(require);
1629 super.writer.endNode();
1632 private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
1633 emitRequireInstanceNode(typeDefinition.requireInstance());
1636 private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
1637 emitBaseIdentities(typeDefinition.getIdentities());
1640 private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
1641 for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
1642 // FIXME: BUG-2444: What if we have locally modified types here?
1643 // is solution to look-up in schema path?
1644 emitTypeNode(typeDefinition.getPath(), subtype);
1648 private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
1649 for (final Bit bit : typeDefinition.getBits()) {
1654 private void emitBit(final Bit bit) {
1655 super.writer.startBitNode(bit.getName());
1656 emitPositionNode(bit.getPosition());
1657 emitDocumentedNode(bit);
1658 super.writer.endNode();
1661 private void emitPositionNode(@Nullable final Long position) {
1662 if (position != null) {
1663 super.writer.startPositionNode(UnsignedInteger.valueOf(position));
1664 super.writer.endNode();
1668 private void emitStatusNode(@Nullable final Status status) {
1669 if (status != null) {
1670 super.writer.startStatusNode(status);
1671 super.writer.endNode();
1675 private void emitConfigNode(final boolean config) {
1676 super.writer.startConfigNode(config);
1677 super.writer.endNode();
1680 private void emitMandatoryNode(final boolean mandatory) {
1681 super.writer.startMandatoryNode(mandatory);
1682 super.writer.endNode();
1685 private void emitPresenceNode(final boolean presence) {
1686 super.writer.startPresenceNode(presence);
1687 super.writer.endNode();
1690 private void emitOrderedBy(final boolean userOrdered) {
1692 super.writer.startOrderedByNode("user");
1694 super.writer.startOrderedByNode("system");
1696 super.writer.endNode();
1699 private void emitMust(@Nullable final MustDefinition mustCondition) {
1700 if (mustCondition != null && mustCondition.getXpath() != null) {
1701 super.writer.startMustNode(mustCondition.getXpath());
1702 mustCondition.getErrorMessage().ifPresent(this::emitErrorMessageNode);
1703 mustCondition.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
1704 emitDocumentedNode(mustCondition);
1705 super.writer.endNode();
1709 private void emitErrorMessageNode(@Nullable final String input) {
1710 super.writer.startErrorMessageNode(input);
1711 super.writer.endNode();
1714 private void emitErrorAppTagNode(final String input) {
1715 super.writer.startErrorAppTagNode(input);
1716 super.writer.endNode();
1719 private void emitMinElementsNode(final Integer min) {
1721 super.writer.startMinElementsNode(min);
1722 super.writer.endNode();
1726 private void emitMaxElementsNode(final Integer max) {
1728 super.writer.startMaxElementsNode(max);
1729 super.writer.endNode();
1733 private void emitValueNode(@Nullable final Integer value) {
1734 if (value != null) {
1735 super.writer.startValueNode(value);
1736 super.writer.endNode();
1740 private void emitDocumentedNode(final DocumentedNode input) {
1741 input.getDescription().ifPresent(this::emitDescriptionNode);
1742 input.getReference().ifPresent(this::emitReferenceNode);
1745 private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
1746 emitStatusNode(input.getStatus());
1747 emitDocumentedNode((DocumentedNode) input);
1750 private void emitGrouping(final GroupingDefinition grouping) {
1751 super.writer.startGroupingNode(grouping.getQName());
1752 emitDocumentedNode(grouping);
1753 emitDataNodeContainer(grouping);
1754 emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
1755 emitNotifications(grouping.getNotifications());
1756 emitActions(grouping.getActions());
1757 super.writer.endNode();
1761 private void emitContainer(final ContainerSchemaNode child) {
1762 super.writer.startContainerNode(child.getQName());
1763 emitConstraints(child.getConstraints());
1764 // FIXME: BUG-2444: whenNode //:Optional
1765 // FIXME: BUG-2444: *(ifFeatureNode )
1766 emitPresenceNode(child.isPresenceContainer());
1767 emitConfigNode(child.isConfiguration());
1768 emitDocumentedNode(child);
1769 emitDataNodeContainer(child);
1770 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1771 emitNotifications(child.getNotifications());
1772 emitActions(child.getActions());
1773 super.writer.endNode();
1777 private void emitConstraints(final ConstraintDefinition constraints) {
1778 constraints.getWhenCondition().ifPresent(this::emitWhen);
1779 for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
1780 emitMust(mustCondition);
1784 private void emitLeaf(final LeafSchemaNode child) {
1785 super.writer.startLeafNode(child.getQName());
1786 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1787 // FIXME: BUG-2444: *(ifFeatureNode )
1788 emitTypeNode(child.getPath(), child.getType());
1789 child.getType().getUnits().ifPresent(this::emitUnitsNode);
1790 emitMustNodes(child.getConstraints().getMustConstraints());
1791 child.getType().getDefaultValue().ifPresent(this::emitDefaultNode);
1792 emitConfigNode(child.isConfiguration());
1793 emitMandatoryNode(child.getConstraints().isMandatory());
1794 emitDocumentedNode(child);
1795 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1796 super.writer.endNode();
1800 private void emitLeafList(final LeafListSchemaNode child) {
1801 super.writer.startLeafListNode(child.getQName());
1803 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1804 // FIXME: BUG-2444: *(ifFeatureNode )
1805 emitTypeNode(child.getPath(), child.getType());
1806 child.getType().getUnits().ifPresent(this::emitUnitsNode);
1807 // FIXME: BUG-2444: unitsNode /Optional
1808 emitMustNodes(child.getConstraints().getMustConstraints());
1809 emitConfigNode(child.isConfiguration());
1810 emitDefaultNodes(child.getDefaults());
1811 emitMinElementsNode(child.getConstraints().getMinElements());
1812 emitMaxElementsNode(child.getConstraints().getMaxElements());
1813 emitOrderedBy(child.isUserOrdered());
1814 emitDocumentedNode(child);
1815 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1816 super.writer.endNode();
1820 private void emitList(final ListSchemaNode child) {
1821 super.writer.startListNode(child.getQName());
1822 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1824 // FIXME: BUG-2444: *(ifFeatureNode )
1825 emitMustNodes(child.getConstraints().getMustConstraints());
1826 emitKey(child.getKeyDefinition());
1827 emitUniqueConstraints(child.getUniqueConstraints());
1828 emitConfigNode(child.isConfiguration());
1829 emitMinElementsNode(child.getConstraints().getMinElements());
1830 emitMaxElementsNode(child.getConstraints().getMaxElements());
1831 emitOrderedBy(child.isUserOrdered());
1832 emitDocumentedNode(child);
1833 emitDataNodeContainer(child);
1834 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1835 emitNotifications(child.getNotifications());
1836 emitActions(child.getActions());
1837 super.writer.endNode();
1841 private void emitMustNodes(final Collection<MustDefinition> mustConstraints) {
1842 for (final MustDefinition must : mustConstraints) {
1847 private void emitKey(final List<QName> keyList) {
1848 if (keyList != null && !keyList.isEmpty()) {
1849 super.writer.startKeyNode(keyList);
1850 super.writer.endNode();
1854 private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
1855 for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
1856 emitUnique(uniqueConstraint);
1860 private void emitUnique(final UniqueConstraint uniqueConstraint) {
1861 super.writer.startUniqueNode(uniqueConstraint);
1862 super.writer.endNode();
1865 private void emitChoice(final ChoiceSchemaNode choice) {
1866 super.writer.startChoiceNode(choice.getQName());
1867 choice.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1868 // FIXME: BUG-2444: *(ifFeatureNode )
1869 // FIXME: BUG-2444: defaultNode //Optional
1870 emitConfigNode(choice.isConfiguration());
1871 emitMandatoryNode(choice.getConstraints().isMandatory());
1872 emitDocumentedNode(choice);
1873 for (final ChoiceCaseNode caze : choice.getCases().values()) {
1874 // TODO: emit short case?
1877 emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
1878 super.writer.endNode();
1881 private void emitCaseNode(final ChoiceCaseNode caze) {
1882 if (!super.emitInstantiated && caze.isAugmenting()) {
1885 super.writer.startCaseNode(caze.getQName());
1886 caze.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1887 // FIXME: BUG-2444: *(ifFeatureNode )
1888 emitDocumentedNode(caze);
1889 emitDataNodeContainer(caze);
1890 emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
1891 super.writer.endNode();
1895 private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
1896 super.writer.startAnyxmlNode(anyxml.getQName());
1897 emitBodyOfDataSchemaNode(anyxml);
1898 super.writer.endNode();
1901 private void emitAnydata(final AnyDataSchemaNode anydata) {
1902 super.writer.startAnydataNode(anydata.getQName());
1903 emitBodyOfDataSchemaNode(anydata);
1904 super.writer.endNode();
1907 private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
1908 dataSchemaNode.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1909 // FIXME: BUG-2444: *(ifFeatureNode )
1910 emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
1911 emitConfigNode(dataSchemaNode.isConfiguration());
1912 emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
1913 emitDocumentedNode(dataSchemaNode);
1914 emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
1917 private void emitUsesNode(final UsesNode usesNode) {
1918 if (super.emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
1919 super.writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
1921 * FIXME: BUG-2444: whenNode / *(ifFeatureNode ) statusNode //
1922 * Optional F : descriptionNode // Optional referenceNode //
1925 for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
1928 for (final AugmentationSchemaNode aug : usesNode.getAugmentations()) {
1929 emitUsesAugmentNode(aug);
1931 super.writer.endNode();
1935 private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
1936 final SchemaPath path = refine.getKey();
1937 final SchemaNode value = refine.getValue();
1938 super.writer.startRefineNode(path);
1940 if (value instanceof LeafSchemaNode) {
1941 emitRefineLeafNodes((LeafSchemaNode) value);
1942 } else if (value instanceof LeafListSchemaNode) {
1943 emitRefineLeafListNodes((LeafListSchemaNode) value);
1944 } else if (value instanceof ListSchemaNode) {
1945 emitRefineListNodes((ListSchemaNode) value);
1946 } else if (value instanceof ChoiceSchemaNode) {
1947 emitRefineChoiceNodes((ChoiceSchemaNode) value);
1948 } else if (value instanceof ChoiceCaseNode) {
1949 emitRefineCaseNodes((ChoiceCaseNode) value);
1950 } else if (value instanceof ContainerSchemaNode) {
1951 emitRefineContainerNodes((ContainerSchemaNode) value);
1952 } else if (value instanceof AnyXmlSchemaNode) {
1953 emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
1955 super.writer.endNode();
1959 private static <T extends SchemaNode> T getOriginalChecked(final T value) {
1960 final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
1961 Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
1962 @SuppressWarnings("unchecked")
1963 final T ret = (T) original.get();
1967 private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
1968 if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
1969 value.getDescription().ifPresent(this::emitDescriptionNode);
1971 if (Objects.deepEquals(original.getReference(), value.getReference())) {
1972 value.getReference().ifPresent(this::emitReferenceNode);
1976 private void emitRefineContainerNodes(final ContainerSchemaNode value) {
1977 final ContainerSchemaNode original = getOriginalChecked(value);
1979 // emitMustNodes(child.getConstraints().getMustConstraints());
1980 if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
1981 emitPresenceNode(value.isPresenceContainer());
1983 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1984 emitConfigNode(value.isConfiguration());
1986 emitDocumentedNodeRefine(original, value);
1990 private void emitRefineLeafNodes(final LeafSchemaNode value) {
1991 final LeafSchemaNode original = getOriginalChecked(value);
1993 // emitMustNodes(child.getConstraints().getMustConstraints());
1994 if (Objects.deepEquals(original.getType().getDefaultValue(), value.getType().getDefaultValue())) {
1995 emitDefaultNode(value.getType().getDefaultValue());
1997 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
1998 emitConfigNode(value.isConfiguration());
2000 emitDocumentedNodeRefine(original, value);
2001 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2002 emitMandatoryNode(value.getConstraints().isMandatory());
2007 private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
2008 final LeafListSchemaNode original = getOriginalChecked(value);
2010 // emitMustNodes(child.getConstraints().getMustConstraints());
2011 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2012 emitConfigNode(value.isConfiguration());
2014 if (Objects.deepEquals(original.getConstraints().getMinElements(),
2015 value.getConstraints().getMinElements())) {
2016 emitMinElementsNode(value.getConstraints().getMinElements());
2018 if (Objects.deepEquals(original.getConstraints().getMaxElements(),
2019 value.getConstraints().getMaxElements())) {
2020 emitMaxElementsNode(value.getConstraints().getMaxElements());
2022 emitDocumentedNodeRefine(original, value);
2026 private void emitRefineListNodes(final ListSchemaNode value) {
2027 final ListSchemaNode original = getOriginalChecked(value);
2029 // emitMustNodes(child.getConstraints().getMustConstraints());
2030 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2031 emitConfigNode(value.isConfiguration());
2033 if (Objects.deepEquals(original.getConstraints().getMinElements(),
2034 value.getConstraints().getMinElements())) {
2035 emitMinElementsNode(value.getConstraints().getMinElements());
2037 if (Objects.deepEquals(original.getConstraints().getMaxElements(),
2038 value.getConstraints().getMaxElements())) {
2039 emitMaxElementsNode(value.getConstraints().getMaxElements());
2041 emitDocumentedNodeRefine(original, value);
2045 private void emitRefineChoiceNodes(final ChoiceSchemaNode value) {
2046 final ChoiceSchemaNode original = getOriginalChecked(value);
2048 // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
2049 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2050 emitConfigNode(value.isConfiguration());
2052 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2053 emitMandatoryNode(value.getConstraints().isMandatory());
2055 emitDocumentedNodeRefine(original, value);
2059 private void emitRefineCaseNodes(final ChoiceCaseNode value) {
2060 final ChoiceCaseNode original = getOriginalChecked(value);
2061 emitDocumentedNodeRefine(original, value);
2065 private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
2066 final AnyXmlSchemaNode original = getOriginalChecked(value);
2069 // emitMustNodes(child.getConstraints().getMustConstraints());
2070 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2071 emitConfigNode(value.isConfiguration());
2073 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2074 emitMandatoryNode(value.getConstraints().isMandatory());
2076 emitDocumentedNodeRefine(original, value);
2080 private void emitUsesAugmentNode(final AugmentationSchemaNode aug) {
2082 * differs only in location in schema, otherwise currently (as of
2083 * RFC6020) it is same, so we could freely reuse path.
2088 private void emitAugment(final AugmentationSchemaNode augmentation) {
2089 super.writer.startAugmentNode(augmentation.getTargetPath());
2090 // FIXME: BUG-2444: whenNode //Optional
2091 // FIXME: BUG-2444: *(ifFeatureNode )
2093 emitDocumentedNode(augmentation);
2094 for (final UsesNode uses : augmentation.getUses()) {
2098 for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
2099 if (childNode instanceof ChoiceCaseNode) {
2100 emitCaseNode((ChoiceCaseNode) childNode);
2102 emitDataSchemaNode(childNode);
2105 emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
2106 emitNotifications(augmentation.getNotifications());
2107 emitActions(augmentation.getActions());
2108 super.writer.endNode();
2111 private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
2112 for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
2113 if (!unknonwnNode.isAddedByAugmentation() && !unknonwnNode.isAddedByUses()) {
2114 emitUnknownStatementNode(unknonwnNode);
2119 private void emitUnknownStatementNode(final UnknownSchemaNode node) {
2120 final StatementDefinition def = getStatementChecked(node.getNodeType());
2121 if (def.getArgumentName() == null) {
2122 super.writer.startUnknownNode(def);
2124 super.writer.startUnknownNode(def, node.getNodeParameter());
2126 emitUnknownStatementNodes(node.getUnknownSchemaNodes());
2127 super.writer.endNode();
2130 private StatementDefinition getStatementChecked(final QName nodeType) {
2131 final StatementDefinition ret = super.extensions.get(nodeType);
2132 Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
2136 private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
2137 if (revisionAwareXPath != null) {
2138 super.writer.startWhenNode(revisionAwareXPath);
2139 super.writer.endNode();
2141 // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
2142 // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
2143 // FIXME: BUG-2444: super.writer.endNode();)
2147 private void emitRpc(final RpcDefinition rpc) {
2148 super.writer.startRpcNode(rpc.getQName());
2149 emitOperationBody(rpc);
2150 super.writer.endNode();
2153 private void emitOperationBody(final OperationDefinition rpc) {
2154 // FIXME: BUG-2444: *(ifFeatureNode )
2155 emitDocumentedNode(rpc);
2157 for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
2158 emitTypedefNode(typedef);
2160 for (final GroupingDefinition grouping : rpc.getGroupings()) {
2161 emitGrouping(grouping);
2163 emitInput(rpc.getInput());
2164 emitOutput(rpc.getOutput());
2165 emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
2168 private void emitActions(final Set<ActionDefinition> actions) {
2169 for (final ActionDefinition actionDefinition : actions) {
2170 emitAction(actionDefinition);
2174 private void emitAction(final ActionDefinition action) {
2175 if (!super.emitInstantiated && (action.isAddedByUses() || action.isAugmenting())) {
2176 // We skip instantiated nodes.
2179 super.writer.startActionNode(action.getQName());
2180 emitOperationBody(action);
2181 super.writer.endNode();
2184 private void emitInput(@Nonnull final ContainerSchemaNode input) {
2185 if (isExplicitStatement(input)) {
2186 super.writer.startInputNode();
2187 emitConstraints(input.getConstraints());
2188 emitDataNodeContainer(input);
2189 emitUnknownStatementNodes(input.getUnknownSchemaNodes());
2190 super.writer.endNode();
2195 private void emitOutput(@Nonnull final ContainerSchemaNode output) {
2196 if (isExplicitStatement(output)) {
2197 super.writer.startOutputNode();
2198 emitConstraints(output.getConstraints());
2199 emitDataNodeContainer(output);
2200 emitUnknownStatementNodes(output.getUnknownSchemaNodes());
2201 super.writer.endNode();
2205 private static boolean isExplicitStatement(final ContainerSchemaNode node) {
2206 return node instanceof EffectiveStatement && ((EffectiveStatement<?, ?>) node).getDeclared()
2207 .getStatementSource() == StatementSource.DECLARATION;
2210 private void emitNotifications(final Set<NotificationDefinition> notifications) {
2211 for (final NotificationDefinition notification : notifications) {
2212 emitNotificationNode(notification);
2216 private void emitNotificationNode(final NotificationDefinition notification) {
2217 if (!super.emitInstantiated && (notification.isAddedByUses() || notification.isAugmenting())) {
2218 // We skip instantiated nodes.
2222 super.writer.startNotificationNode(notification.getQName());
2223 // FIXME: BUG-2444: *(ifFeatureNode )
2224 for (final MustDefinition mustCondition : notification.getMustConstraints()) {
2225 emitMust(mustCondition);
2227 emitDocumentedNode(notification);
2228 emitDataNodeContainer(notification);
2229 emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
2230 super.writer.endNode();
2234 private void emitDeviation(final Deviation deviation) {
2236 * FIXME: BUG-2444: Deviation is not modeled properly and we are
2237 * loosing lot of information in order to export it properly
2239 * super.writer.startDeviationNode(deviation.getTargetPath());
2241 * :descriptionNode //:Optional
2244 * emitReferenceNode(deviation.getReference());
2245 * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
2246 * :deviateDeleteNode)) :super.writer.endNode();