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.base.Strings;
14 import com.google.common.collect.Collections2;
15 import com.google.common.collect.Range;
16 import com.google.common.collect.RangeSet;
17 import com.google.common.primitives.UnsignedInteger;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.List;
23 import java.util.Map.Entry;
24 import java.util.Objects;
25 import java.util.Optional;
27 import javax.annotation.Nonnull;
28 import javax.annotation.Nullable;
29 import javax.annotation.concurrent.NotThreadSafe;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.common.Revision;
32 import org.opendaylight.yangtools.yang.common.YangVersion;
33 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
34 import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
38 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
40 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
42 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
43 import org.opendaylight.yangtools.yang.model.api.Deviation;
44 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
45 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
46 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
47 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
48 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
50 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
51 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
52 import org.opendaylight.yangtools.yang.model.api.Module;
53 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
54 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
55 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
56 import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
57 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
58 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
59 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
60 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
61 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
62 import org.opendaylight.yangtools.yang.model.api.Status;
63 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
64 import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
65 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
66 import org.opendaylight.yangtools.yang.model.api.UsesNode;
67 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
68 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
69 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
70 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
71 import org.opendaylight.yangtools.yang.model.api.stmt.ActionStatement;
72 import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement;
73 import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement;
74 import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
75 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
76 import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement;
77 import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
78 import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement;
79 import org.opendaylight.yangtools.yang.model.api.stmt.BodyGroup;
80 import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
81 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
82 import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
83 import org.opendaylight.yangtools.yang.model.api.stmt.ContactStatement;
84 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
85 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionContainer;
86 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement;
87 import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
88 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
89 import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
90 import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
91 import org.opendaylight.yangtools.yang.model.api.stmt.DocumentationGroup;
92 import org.opendaylight.yangtools.yang.model.api.stmt.DocumentedConstraintGroup;
93 import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement;
94 import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement;
95 import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
96 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement;
97 import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement;
98 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
99 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
100 import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
101 import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
102 import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
103 import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
104 import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
105 import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
106 import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
107 import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
108 import org.opendaylight.yangtools.yang.model.api.stmt.LinkageGroup;
109 import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
110 import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
111 import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsStatement;
112 import org.opendaylight.yangtools.yang.model.api.stmt.MetaGroup;
113 import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
114 import org.opendaylight.yangtools.yang.model.api.stmt.ModifierStatement;
115 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
116 import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement;
117 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
118 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
119 import org.opendaylight.yangtools.yang.model.api.stmt.OperationGroup;
120 import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
121 import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationStatement;
122 import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
123 import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement;
124 import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement;
125 import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement;
126 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
127 import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
128 import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
129 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
130 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
131 import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement;
132 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement;
133 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionGroup;
134 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
135 import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
136 import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
137 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
138 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
139 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
140 import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
141 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement;
142 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
143 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
144 import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement;
145 import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
146 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
147 import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
148 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
149 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
150 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
151 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
152 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
153 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
154 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
155 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
156 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
157 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
158 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
159 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
160 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
161 import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
162 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
163 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
164 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
165 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
166 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
167 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
171 abstract class SchemaContextEmitter {
173 final YangModuleWriter writer;
174 final boolean emitInstantiated;
175 final boolean emitUses;
176 final Map<QName, StatementDefinition> extensions;
177 final YangVersion yangVersion;
179 SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
180 final YangVersion yangVersion) {
181 this(writer, extensions, yangVersion, false, true);
184 SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
185 final YangVersion yangVersion, final boolean emitInstantiated, final boolean emitUses) {
186 this.writer = Preconditions.checkNotNull(writer);
187 this.emitInstantiated = emitInstantiated;
188 this.emitUses = emitUses;
189 this.extensions = Preconditions.checkNotNull(extensions);
190 this.yangVersion = yangVersion;
193 static void writeToStatementWriter(final Module module, final SchemaContext ctx,
194 final StatementTextWriter statementWriter, final boolean emitInstantiated) {
195 final YangModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
196 final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
197 if (module instanceof EffectiveStatement && !emitInstantiated) {
199 * if module is an effective statement and we don't want to export
200 * instantiated statements (e.g. statements added by uses or
201 * augment) we can get declared form i.e. ModuleStatement and then
202 * use DeclaredSchemaContextEmitter
204 new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion())
205 .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
208 * if we don't have access to declared form of supplied module or we
209 * want to emit also instantiated statements (e.g. statements added
210 * by uses or augment), we use EffectiveSchemaContextEmitter.
212 new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion(), emitInstantiated)
217 // FIXME: Probably should be moved to utils bundle.
218 static <T> boolean isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
219 final Iterator<T> prefixIt = prefix.iterator();
220 final Iterator<T> otherIt = other.iterator();
221 while (prefixIt.hasNext()) {
222 if (!otherIt.hasNext()) {
225 if (!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
232 static class DeclaredSchemaContextEmitter extends SchemaContextEmitter {
234 DeclaredSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
235 final YangVersion yangVersion) {
236 super(writer, extensions, yangVersion);
239 void emitModule(final DeclaredStatement<?> declaredRootStmt) {
240 if (declaredRootStmt instanceof ModuleStatement) {
241 emitModule((ModuleStatement) declaredRootStmt);
242 } else if (declaredRootStmt instanceof SubmoduleStatement) {
243 emitSubmodule((SubmoduleStatement) declaredRootStmt);
245 throw new UnsupportedOperationException(
246 String.format("Yin export: unsupported declared statement %s", declaredRootStmt));
250 private void emitModule(final ModuleStatement module) {
251 super.writer.startModuleNode(module.rawArgument());
252 emitModuleHeader(module);
253 emitLinkageNodes(module);
254 emitMetaNodes(module);
255 emitRevisionNodes(module);
256 emitBodyNodes(module);
257 emitUnknownStatementNodes(module);
258 super.writer.endNode();
261 private void emitModuleHeader(final ModuleStatement input) {
262 emitYangVersionNode(input.getYangVersion());
263 emitNamespace(input.getNamespace());
264 emitPrefixNode(input.getPrefix());
267 private void emitSubmodule(final SubmoduleStatement submodule) {
268 super.writer.startSubmoduleNode(submodule.rawArgument());
269 emitSubmoduleHeaderNodes(submodule);
270 emitLinkageNodes(submodule);
271 emitMetaNodes(submodule);
272 emitRevisionNodes(submodule);
273 emitBodyNodes(submodule);
274 emitUnknownStatementNodes(submodule);
275 super.writer.endNode();
278 private void emitSubmoduleHeaderNodes(final SubmoduleStatement input) {
279 emitYangVersionNode(input.getYangVersion());
280 emitBelongsTo(input.getBelongsTo());
283 private void emitBelongsTo(final BelongsToStatement belongsTo) {
284 super.writer.startBelongsToNode(belongsTo.rawArgument());
285 emitPrefixNode(belongsTo.getPrefix());
286 super.writer.endNode();
289 private void emitMetaNodes(final MetaGroup input) {
290 emitOrganizationNode(input.getOrganization());
291 emitContact(input.getContact());
292 emitDescriptionNode(input.getDescription());
293 emitReferenceNode(input.getReference());
296 private void emitLinkageNodes(final LinkageGroup input) {
297 for (final ImportStatement importNode : input.getImports()) {
298 emitImport(importNode);
300 for (final IncludeStatement importNode : input.getIncludes()) {
301 emitInclude(importNode);
305 private void emitRevisionNodes(final RevisionGroup input) {
306 emitRevisions(input.getRevisions());
309 private void emitBodyNodes(final BodyGroup input) {
311 for (final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension : input
313 emitExtension(extension);
315 for (final FeatureStatement definition : input.getFeatures()) {
316 emitFeature(definition);
318 for (final IdentityStatement identity : input.getIdentities()) {
319 emitIdentity(identity);
321 for (final DeviationStatement deviation : input.getDeviations()) {
322 emitDeviation(deviation);
325 emitDataNodeContainer(input);
327 for (final AugmentStatement augmentation : input.getAugments()) {
328 emitAugment(augmentation);
330 for (final RpcStatement rpc : input.getRpcs()) {
334 emitNotifications(input.getNotifications());
337 private void emitDataNodeContainer(final DataDefinitionContainer input) {
338 for (final DataDefinitionStatement child : input.getDataDefinitions()) {
339 emitDataSchemaNode(child);
343 private void emitDataNodeContainer(final DataDefinitionContainer.WithReusableDefinitions input) {
344 for (final TypedefStatement typedef : input.getTypedefs()) {
345 emitTypedefNode(typedef);
347 for (final GroupingStatement grouping : input.getGroupings()) {
348 emitGrouping(grouping);
350 for (final DataDefinitionStatement child : input.getDataDefinitions()) {
351 emitDataSchemaNode(child);
355 private void emitDataSchemaNode(final DataDefinitionStatement child) {
356 if (child instanceof ContainerStatement) {
357 emitContainer((ContainerStatement) child);
358 } else if (child instanceof LeafStatement) {
359 emitLeaf((LeafStatement) child);
360 } else if (child instanceof LeafListStatement) {
361 emitLeafList((LeafListStatement) child);
362 } else if (child instanceof ListStatement) {
363 emitList((ListStatement) child);
364 } else if (child instanceof ChoiceStatement) {
365 emitChoice((ChoiceStatement) child);
366 } else if (child instanceof AnyxmlStatement) {
367 emitAnyxml((AnyxmlStatement) child);
368 } else if (child instanceof AnydataStatement) {
369 emitAnydata((AnydataStatement) child);
370 } else if (child instanceof UsesStatement) {
371 emitUsesNode((UsesStatement) child);
373 throw new UnsupportedOperationException("Not supported DataStatement type " + child.getClass());
377 private void emitYangVersionNode(@Nullable final YangVersionStatement yangVersionStatement) {
378 if (yangVersionStatement != null) {
379 super.writer.startYangVersionNode(yangVersionStatement.rawArgument());
380 super.writer.endNode();
384 private void emitImport(final ImportStatement importNode) {
385 super.writer.startImportNode(importNode.rawArgument());
386 emitDocumentedNode(importNode);
387 emitPrefixNode(importNode.getPrefix());
388 emitRevisionDateNode(importNode.getRevisionDate());
389 super.writer.endNode();
392 private void emitInclude(final IncludeStatement include) {
393 super.writer.startIncludeNode(include.rawArgument());
394 emitDocumentedNode(include);
395 emitRevisionDateNode(include.getRevisionDate());
396 super.writer.endNode();
399 private void emitNamespace(final NamespaceStatement namespaceStatement) {
400 Preconditions.checkNotNull(namespaceStatement, "Namespace must not be null");
401 super.writer.startNamespaceNode(namespaceStatement.getUri());
402 super.writer.endNode();
405 private void emitPrefixNode(final PrefixStatement prefixStatement) {
406 Preconditions.checkNotNull(prefixStatement, "Prefix must not be null");
407 super.writer.startPrefixNode(prefixStatement.rawArgument());
408 super.writer.endNode();
411 private void emitOrganizationNode(@Nullable final OrganizationStatement organizationStatement) {
412 if (organizationStatement != null) {
413 super.writer.startOrganizationNode(organizationStatement.rawArgument());
414 super.writer.endNode();
418 private void emitContact(@Nullable final ContactStatement contactStatement) {
419 if (contactStatement != null) {
420 super.writer.startContactNode(contactStatement.rawArgument());
421 super.writer.endNode();
425 private void emitDescriptionNode(@Nullable final DescriptionStatement descriptionStatement) {
426 if (descriptionStatement != null) {
427 super.writer.startDescriptionNode(descriptionStatement.rawArgument());
428 super.writer.endNode();
432 private void emitReferenceNode(@Nullable final ReferenceStatement referenceStatement) {
433 if (referenceStatement != null) {
434 super.writer.startReferenceNode(referenceStatement.rawArgument());
435 super.writer.endNode();
439 private void emitUnitsNode(@Nullable final UnitsStatement unitsStatement) {
440 if (unitsStatement != null) {
441 super.writer.startUnitsNode(unitsStatement.rawArgument());
442 super.writer.endNode();
446 private void emitRevisions(final Collection<? extends RevisionStatement> revisions) {
447 for (final RevisionStatement revisionStatement : revisions) {
448 emitRevision(revisionStatement);
452 private void emitRevision(final RevisionStatement revision) {
453 super.writer.startRevisionNode(revision.rawArgument());
454 emitDocumentedNode(revision);
455 super.writer.endNode();
458 private void emitRevisionDateNode(@Nullable final RevisionDateStatement revisionDateStatement) {
459 if (revisionDateStatement != null) {
460 super.writer.startRevisionDateNode(revisionDateStatement.rawArgument());
461 super.writer.endNode();
465 private void emitExtension(final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension) {
466 super.writer.startExtensionNode(extension.rawArgument());
467 emitArgument(extension.getArgument());
468 emitDocumentedNodeWithStatus(extension);
469 emitUnknownStatementNodes(extension);
470 super.writer.endNode();
473 private void emitArgument(@Nullable final ArgumentStatement input) {
475 super.writer.startArgumentNode(input.rawArgument());
476 emitYinElement(input.getYinElement());
477 super.writer.endNode();
481 private void emitYinElement(@Nullable final YinElementStatement yinElementStatement) {
482 if (yinElementStatement != null) {
483 super.writer.startYinElementNode(yinElementStatement.rawArgument());
484 super.writer.endNode();
488 private void emitIdentity(final IdentityStatement identity) {
489 super.writer.startIdentityNode(identity.rawArgument());
490 emitBaseIdentities(identity.getBases());
491 emitStatusNode(identity.getStatus());
492 emitDescriptionNode(identity.getDescription());
493 emitReferenceNode(identity.getReference());
494 super.writer.endNode();
497 private void emitBaseIdentities(final Collection<? extends BaseStatement> collection) {
498 for (final BaseStatement baseStmt : collection) {
503 private void emitBase(final BaseStatement baseStmt) {
504 super.writer.startBaseNode(baseStmt.rawArgument());
505 super.writer.endNode();
508 private void emitFeature(final FeatureStatement feature) {
509 super.writer.startFeatureNode(feature.rawArgument());
510 emitIfFeatures(feature.getIfFeatures());
511 emitDocumentedNodeWithStatus(feature);
512 super.writer.endNode();
515 private void emitIfFeatures(final Collection<? extends IfFeatureStatement> ifFeatures) {
516 for (final IfFeatureStatement ifFeatureStatement : ifFeatures) {
517 emitIfFeature(ifFeatureStatement);
521 private void emitIfFeature(final IfFeatureStatement ifFeature) {
522 super.writer.startIfFeatureNode(ifFeature.rawArgument());
523 super.writer.endNode();
526 private void emitTypedefNode(final TypedefStatement typedef) {
527 super.writer.startTypedefNode(typedef.rawArgument());
528 emitType(typedef.getType());
529 emitUnitsNode(typedef.getUnits());
530 emitDefaultNode(typedef.getDefault());
531 emitStatusNode(typedef.getStatus());
532 emitDescriptionNode(typedef.getDescription());
533 emitReferenceNode(typedef.getReference());
534 emitUnknownStatementNodes(typedef);
535 super.writer.endNode();
538 private void emitType(final TypeStatement typeStatement) {
539 super.writer.startTypeNode(typeStatement.rawArgument());
540 for (final DeclaredStatement<?> typeSubstmt : typeStatement.declaredSubstatements()) {
541 if (typeSubstmt instanceof RangeStatement) {
542 emitRange((RangeStatement) typeSubstmt);
543 } else if (typeSubstmt instanceof LengthStatement) {
544 emitLength((LengthStatement) typeSubstmt);
545 } else if (typeSubstmt instanceof PatternStatement) {
546 emitPattern((PatternStatement) typeSubstmt);
547 } else if (typeSubstmt instanceof FractionDigitsStatement) {
548 emitFractionDigits((FractionDigitsStatement) typeSubstmt);
549 } else if (typeSubstmt instanceof EnumStatement) {
550 emitEnum((EnumStatement) typeSubstmt);
551 } else if (typeSubstmt instanceof PathStatement) {
552 emitPath((PathStatement) typeSubstmt);
553 } else if (typeSubstmt instanceof RequireInstanceStatement) {
554 emitRequireInstance((RequireInstanceStatement) typeSubstmt);
555 } else if (typeSubstmt instanceof BaseStatement) {
556 emitBase((BaseStatement) typeSubstmt);
557 } else if (typeSubstmt instanceof BitStatement) {
558 emitBit((BitStatement) typeSubstmt);
559 } else if (typeSubstmt instanceof TypeStatement) {
560 emitType((TypeStatement) typeSubstmt);
563 super.writer.endNode();
566 private void emitRange(final RangeStatement range) {
567 super.writer.startRangeNode(range.rawArgument());
568 emitDocumentedConstraint(range);
569 super.writer.endNode();
572 private void emitFractionDigits(final FractionDigitsStatement fractionDigits) {
573 super.writer.startFractionDigitsNode(fractionDigits.rawArgument());
574 super.writer.endNode();
577 private void emitLength(final LengthStatement lengthStatement) {
578 super.writer.startLengthNode(lengthStatement.rawArgument());
579 emitDocumentedConstraint(lengthStatement);
580 super.writer.endNode();
583 private void emitPattern(final PatternStatement pattern) {
584 super.writer.startPatternNode(pattern.rawArgument());
585 emitModifier(pattern.getModifierStatement());
586 emitDocumentedConstraint(pattern);
587 super.writer.endNode();
590 private void emitModifier(final ModifierStatement modifierStatement) {
591 if (modifierStatement != null) {
592 super.writer.startModifierNode(modifierStatement.rawArgument());
593 super.writer.endNode();
597 private void emitDefaultNodes(final Collection<? extends DefaultStatement> collection) {
598 for (final DefaultStatement defaultValue : collection) {
599 emitDefaultNode(defaultValue);
603 private void emitDefaultNode(@Nullable final DefaultStatement defaultStmt) {
604 if (defaultStmt != null) {
605 super.writer.startDefaultNode(defaultStmt.rawArgument());
606 super.writer.endNode();
610 private void emitEnum(final EnumStatement enumStmt) {
611 super.writer.startEnumNode(enumStmt.rawArgument());
612 emitDocumentedNodeWithStatus(enumStmt);
613 emitValueNode(enumStmt.getValue());
614 super.writer.endNode();
617 private void emitPath(final PathStatement path) {
618 super.writer.startPathNode(path.rawArgument());
619 super.writer.endNode();
622 private void emitRequireInstance(final RequireInstanceStatement require) {
623 super.writer.startRequireInstanceNode(require.rawArgument());
624 super.writer.endNode();
627 private void emitBit(final BitStatement bit) {
628 super.writer.startBitNode(bit.rawArgument());
629 emitPositionNode(bit.getPosition());
630 emitDocumentedNodeWithStatus(bit);
631 super.writer.endNode();
634 private void emitPositionNode(@Nullable final PositionStatement positionStatement) {
635 if (positionStatement != null) {
636 super.writer.startPositionNode(positionStatement.rawArgument());
637 super.writer.endNode();
641 private void emitStatusNode(@Nullable final StatusStatement statusStatement) {
642 if (statusStatement != null) {
643 super.writer.startStatusNode(statusStatement.rawArgument());
644 super.writer.endNode();
648 private void emitConfigNode(@Nullable final ConfigStatement configStatement) {
649 if (configStatement != null) {
650 super.writer.startConfigNode(configStatement.rawArgument());
651 super.writer.endNode();
655 private void emitMandatoryNode(@Nullable final MandatoryStatement mandatoryStatement) {
656 if (mandatoryStatement != null) {
657 super.writer.startMandatoryNode(mandatoryStatement.rawArgument());
658 super.writer.endNode();
662 private void emitPresenceNode(@Nullable final PresenceStatement presenceStatement) {
663 if (presenceStatement != null) {
664 super.writer.startPresenceNode(presenceStatement.rawArgument());
665 super.writer.endNode();
669 private void emitOrderedBy(@Nullable final OrderedByStatement orderedByStatement) {
670 if (orderedByStatement != null) {
671 super.writer.startOrderedByNode(orderedByStatement.rawArgument());
672 super.writer.endNode();
676 private void emitMust(@Nullable final MustStatement must) {
678 super.writer.startMustNode(must.rawArgument());
679 emitErrorMessageNode(must.getErrorMessageStatement());
680 emitErrorAppTagNode(must.getErrorAppTagStatement());
681 emitDescriptionNode(must.getDescription());
682 emitReferenceNode(must.getReference());
683 super.writer.endNode();
687 private void emitErrorMessageNode(@Nullable final ErrorMessageStatement errorMessageStatement) {
688 if (errorMessageStatement != null) {
689 super.writer.startErrorMessageNode(errorMessageStatement.rawArgument());
690 super.writer.endNode();
694 private void emitErrorAppTagNode(@Nullable final ErrorAppTagStatement errorAppTagStatement) {
695 if (errorAppTagStatement != null) {
696 super.writer.startErrorAppTagNode(errorAppTagStatement.rawArgument());
697 super.writer.endNode();
701 private void emitMinElementsNode(@Nullable final MinElementsStatement minElementsStatement) {
702 if (minElementsStatement != null) {
703 super.writer.startMinElementsNode(minElementsStatement.rawArgument());
704 super.writer.endNode();
708 private void emitMaxElementsNode(@Nullable final MaxElementsStatement maxElementsStatement) {
709 if (maxElementsStatement != null) {
710 super.writer.startMaxElementsNode(maxElementsStatement.rawArgument());
711 super.writer.endNode();
715 private void emitValueNode(@Nullable final ValueStatement valueStatement) {
716 if (valueStatement != null) {
717 super.writer.startValueNode(valueStatement.rawArgument());
718 super.writer.endNode();
722 private void emitDocumentedNodeWithStatus(final DocumentationGroup.WithStatus input) {
723 emitStatusNode(input.getStatus());
724 emitDocumentedNode(input);
727 private void emitDocumentedNode(final DocumentationGroup input) {
728 emitDescriptionNode(input.getDescription());
729 emitReferenceNode(input.getReference());
732 private void emitDocumentedConstraint(final DocumentedConstraintGroup input) {
733 emitDescriptionNode(input.getDescription());
734 emitReferenceNode(input.getReference());
735 emitErrorMessageNode(input.getErrorMessageStatement());
736 emitErrorAppTagNode(input.getErrorAppTagStatement());
739 private void emitGrouping(final GroupingStatement grouping) {
740 super.writer.startGroupingNode(grouping.rawArgument());
741 emitDocumentedNodeWithStatus(grouping);
742 emitDataNodeContainer(grouping);
743 emitUnknownStatementNodes(grouping);
744 emitNotifications(grouping.getNotifications());
745 emitActions(grouping.getActions());
746 super.writer.endNode();
750 private void emitContainer(final ContainerStatement container) {
751 super.writer.startContainerNode(container.rawArgument());
752 emitWhen(container.getWhenStatement());
753 emitMustNodes(container.getMusts());
754 emitIfFeatures(container.getIfFeatures());
755 emitPresenceNode(container.getPresence());
756 emitConfigNode(container.getConfig());
757 emitDocumentedNodeWithStatus(container);
758 emitDataNodeContainer(container);
759 emitUnknownStatementNodes(container);
760 emitNotifications(container.getNotifications());
761 emitActions(container.getActions());
762 super.writer.endNode();
766 private void emitLeaf(final LeafStatement leaf) {
767 super.writer.startLeafNode(leaf.rawArgument());
768 emitWhen(leaf.getWhenStatement());
769 emitIfFeatures(leaf.getIfFeatures());
770 emitType(leaf.getType());
771 emitUnitsNode(leaf.getUnits());
772 emitMustNodes(leaf.getMusts());
773 emitDefaultNode(leaf.getDefault());
774 emitConfigNode(leaf.getConfig());
775 emitMandatoryNode(leaf.getMandatory());
776 emitDocumentedNodeWithStatus(leaf);
777 emitUnknownStatementNodes(leaf);
778 super.writer.endNode();
781 private void emitLeafList(final LeafListStatement leafList) {
782 super.writer.startLeafListNode(leafList.rawArgument());
783 emitWhen(leafList.getWhenStatement());
784 emitIfFeatures(leafList.getIfFeatures());
785 emitType(leafList.getType());
786 emitUnitsNode(leafList.getUnits());
787 emitMustNodes(leafList.getMusts());
788 emitConfigNode(leafList.getConfig());
789 emitDefaultNodes(leafList.getDefaults());
790 emitMinElementsNode(leafList.getMinElements());
791 emitMaxElementsNode(leafList.getMaxElements());
792 emitOrderedBy(leafList.getOrderedBy());
793 emitDocumentedNodeWithStatus(leafList);
794 emitUnknownStatementNodes(leafList);
795 super.writer.endNode();
798 private void emitList(final ListStatement list) {
799 super.writer.startListNode(list.rawArgument());
800 emitWhen(list.getWhenStatement());
801 emitIfFeatures(list.getIfFeatures());
802 emitMustNodes(list.getMusts());
803 emitKey(list.getKey());
804 emitUniqueConstraints(list.getUnique());
805 emitConfigNode(list.getConfig());
806 emitMinElementsNode(list.getMinElements());
807 emitMaxElementsNode(list.getMaxElements());
808 emitOrderedBy(list.getOrderedBy());
809 emitDocumentedNodeWithStatus(list);
810 emitDataNodeContainer(list);
811 emitUnknownStatementNodes(list);
812 emitNotifications(list.getNotifications());
813 emitActions(list.getActions());
814 super.writer.endNode();
817 private void emitMustNodes(final Collection<? extends MustStatement> collection) {
818 for (final MustStatement must : collection) {
823 private void emitKey(final KeyStatement keyStatement) {
824 if (keyStatement != null) {
825 super.writer.startKeyNode(keyStatement.rawArgument());
826 super.writer.endNode();
830 private void emitUniqueConstraints(final Collection<? extends UniqueStatement> collection) {
831 for (final UniqueStatement uniqueConstraint : collection) {
832 emitUnique(uniqueConstraint);
836 private void emitUnique(final UniqueStatement uniqueConstraint) {
837 if (uniqueConstraint != null) {
838 super.writer.startUniqueNode(uniqueConstraint.rawArgument());
839 super.writer.endNode();
843 private void emitChoice(final ChoiceStatement choice) {
844 super.writer.startChoiceNode(choice.rawArgument());
845 emitWhen(choice.getWhenStatement());
846 emitIfFeatures(choice.getIfFeatures());
847 emitDefaultNode(choice.getDefault());
848 emitConfigNode(choice.getConfig());
849 emitMandatoryNode(choice.getMandatory());
850 emitDocumentedNodeWithStatus(choice);
851 emitCases(choice.getCases());
852 emitUnknownStatementNodes(choice);
853 super.writer.endNode();
856 private void emitShortCases(final Collection<? extends DeclaredStatement<?>> declaredSubstatements) {
857 for (final DeclaredStatement<?> child : declaredSubstatements) {
858 if (child instanceof ContainerStatement) {
859 emitContainer((ContainerStatement) child);
860 } else if (child instanceof LeafStatement) {
861 emitLeaf((LeafStatement) child);
862 } else if (child instanceof LeafListStatement) {
863 emitLeafList((LeafListStatement) child);
864 } else if (child instanceof ListStatement) {
865 emitList((ListStatement) child);
866 } else if (child instanceof ChoiceStatement) {
867 emitChoice((ChoiceStatement) child);
868 } else if (child instanceof AnyxmlStatement) {
869 emitAnyxml((AnyxmlStatement) child);
870 } else if (child instanceof AnydataStatement) {
871 emitAnydata((AnydataStatement) child);
876 private void emitCases(final Collection<? extends CaseStatement> cases) {
877 for (final CaseStatement caze : cases) {
878 if (isExplicitStatement(caze)) {
881 final Collection<? extends DeclaredStatement<?>> shortCaseChilds = caze.declaredSubstatements();
882 Preconditions.checkState(shortCaseChilds.size() == 1,
883 "Only one child is allowed for each short case node");
884 emitShortCases(shortCaseChilds);
889 private void emitCaseNode(final CaseStatement caze) {
890 super.writer.startCaseNode(caze.rawArgument());
891 emitWhen(caze.getWhenStatement());
892 emitIfFeatures(caze.getIfFeatures());
893 emitDocumentedNodeWithStatus(caze);
894 emitDataNodeContainer(caze);
895 emitUnknownStatementNodes(caze);
896 super.writer.endNode();
899 private void emitAnyxml(final AnyxmlStatement anyxml) {
900 super.writer.startAnyxmlNode(anyxml.rawArgument());
901 emitDocumentedNodeWithStatus(anyxml);
902 emitWhen(anyxml.getWhenStatement());
903 emitIfFeatures(anyxml.getIfFeatures());
904 emitMustNodes(anyxml.getMusts());
905 emitConfigNode(anyxml.getConfig());
906 emitMandatoryNode(anyxml.getMandatory());
907 emitDocumentedNodeWithStatus(anyxml);
908 emitUnknownStatementNodes(anyxml);
909 super.writer.endNode();
912 private void emitAnydata(final AnydataStatement anydata) {
913 super.writer.startAnydataNode(anydata.rawArgument());
914 emitWhen(anydata.getWhenStatement());
915 emitIfFeatures(anydata.getIfFeatures());
916 emitMustNodes(anydata.getMusts());
917 emitConfigNode(anydata.getConfig());
918 emitMandatoryNode(anydata.getMandatory());
919 emitDocumentedNodeWithStatus(anydata);
920 emitUnknownStatementNodes(anydata);
921 super.writer.endNode();
924 private void emitUsesNode(final UsesStatement uses) {
925 super.writer.startUsesNode(uses.rawArgument());
926 emitWhen(uses.getWhenStatement());
927 emitIfFeatures(uses.getIfFeatures());
928 emitDocumentedNodeWithStatus(uses);
929 for (final RefineStatement refine : uses.getRefines()) {
932 for (final AugmentStatement aug : uses.getAugments()) {
933 emitUsesAugmentNode(aug);
935 super.writer.endNode();
938 private void emitRefine(final RefineStatement refine) {
939 super.writer.startRefineNode(refine.rawArgument());
940 emitDocumentedNode(refine);
941 emitIfFeatures(refine.getIfFeatures());
942 emitMustNodes(refine.getMusts());
943 emitPresenceNode(refine.getPresence());
944 emitDefaultNodes(refine.getDefaults());
945 emitConfigNode(refine.getConfig());
946 emitMandatoryNode(refine.getMandatory());
947 emitMinElementsNode(refine.getMinElements());
948 emitMaxElementsNode(refine.getMaxElements());
949 super.writer.endNode();
952 private void emitUsesAugmentNode(final AugmentStatement aug) {
954 * differs only in location in schema, otherwise currently (as of
955 * RFC6020) it is same, so we could freely reuse path.
960 private void emitAugment(final AugmentStatement augmentation) {
961 super.writer.startAugmentNode(augmentation.rawArgument());
962 emitIfFeatures(augmentation.getIfFeatures());
963 emitWhen(augmentation.getWhenStatement());
964 emitDocumentedNodeWithStatus(augmentation);
965 emitDataNodeContainer(augmentation);
966 emitCases(augmentation.getCases());
967 emitUnknownStatementNodes(augmentation);
968 emitNotifications(augmentation.getNotifications());
969 emitActions(augmentation.getActions());
970 super.writer.endNode();
973 private void emitUnknownStatementNodes(final DeclaredStatement<?> decaredStmt) {
974 final Collection<? extends DeclaredStatement<?>> unknownStmts = Collections2
975 .filter(decaredStmt.declaredSubstatements(), Predicates.instanceOf(UnknownStatement.class));
976 for (final DeclaredStatement<?> unknonwnStmt : unknownStmts) {
977 emitUnknownStatementNode(unknonwnStmt);
981 private void emitUnknownStatementNode(final DeclaredStatement<?> unknonwnStmt) {
982 final StatementDefinition def = unknonwnStmt.statementDefinition();
983 if (def.getArgumentName() == null) {
984 super.writer.startUnknownNode(def);
986 super.writer.startUnknownNode(def, unknonwnStmt.rawArgument());
988 emitUnknownStatementNodes(unknonwnStmt);
989 super.writer.endNode();
992 private void emitWhen(final WhenStatement whenStatement) {
993 if (whenStatement != null) {
994 super.writer.startWhenNode(whenStatement.rawArgument());
995 emitDocumentedNode(whenStatement);
996 super.writer.endNode();
1000 private void emitRpc(final RpcStatement rpc) {
1001 super.writer.startRpcNode(rpc.rawArgument());
1002 emitOperationBody(rpc);
1003 emitUnknownStatementNodes(rpc);
1004 super.writer.endNode();
1007 private void emitOperationBody(final OperationGroup operationStmt) {
1008 emitIfFeatures(operationStmt.getIfFeatures());
1009 emitStatusNode(operationStmt.getStatus());
1010 emitDescriptionNode(operationStmt.getDescription());
1011 emitReferenceNode(operationStmt.getReference());
1013 for (final TypedefStatement typedef : operationStmt.getTypedefs()) {
1014 emitTypedefNode(typedef);
1016 for (final GroupingStatement grouping : operationStmt.getGroupings()) {
1017 emitGrouping(grouping);
1019 emitInput(operationStmt.getInput());
1020 emitOutput(operationStmt.getOutput());
1023 private void emitActions(final Collection<? extends ActionStatement> collection) {
1024 for (final ActionStatement actionDefinition : collection) {
1025 emitAction(actionDefinition);
1029 private void emitAction(final ActionStatement actionDefinition) {
1030 super.writer.startActionNode(actionDefinition.rawArgument());
1031 emitOperationBody(actionDefinition);
1032 emitUnknownStatementNodes(actionDefinition);
1033 super.writer.endNode();
1036 private void emitInput(final InputStatement inputStatement) {
1037 if (isExplicitStatement(inputStatement)) {
1038 super.writer.startInputNode();
1039 emitMustNodes(inputStatement.getMusts());
1040 emitDataNodeContainer(inputStatement);
1041 emitUnknownStatementNodes(inputStatement);
1042 super.writer.endNode();
1046 private void emitOutput(final OutputStatement output) {
1047 if (isExplicitStatement(output)) {
1048 super.writer.startOutputNode();
1049 emitMustNodes(output.getMusts());
1050 emitDataNodeContainer(output);
1051 emitUnknownStatementNodes(output);
1052 super.writer.endNode();
1056 private static boolean isExplicitStatement(final DeclaredStatement<?> stmt) {
1057 return stmt != null && stmt.getStatementSource() == StatementSource.DECLARATION;
1060 private void emitNotifications(final Collection<? extends NotificationStatement> collection) {
1061 for (final NotificationStatement notification : collection) {
1062 emitNotificationNode(notification);
1066 private void emitNotificationNode(final NotificationStatement notification) {
1067 super.writer.startNotificationNode(notification.rawArgument());
1068 emitIfFeatures(notification.getIfFeatures());
1069 emitMustNodes(notification.getMusts());
1070 emitDocumentedNodeWithStatus(notification);
1071 emitDataNodeContainer(notification);
1072 emitUnknownStatementNodes(notification);
1073 super.writer.endNode();
1076 private void emitDeviation(final DeviationStatement deviation) {
1077 super.writer.startDeviationNode(deviation.rawArgument());
1078 emitDeviateStatements(deviation.getDeviateStatements());
1079 emitUnknownStatementNodes(deviation);
1080 super.writer.endNode();
1083 private void emitDeviateStatements(final Collection<? extends DeviateStatement> deviateStatements) {
1084 for (final DeviateStatement deviateStatement : deviateStatements) {
1085 emitDeviate(deviateStatement);
1089 private void emitDeviate(final DeviateStatement deviateStatement) {
1090 super.writer.startDeviateNode(deviateStatement.rawArgument());
1092 * :FIXME Currently, DeviateStatementImpl contains implementation
1093 * for all deviate types (i.e. add, replace, delete). However it
1094 * would be better to create subinterfaces of DeviateStatement for
1095 * each deviate type (i.e. AddDeviateStatement,
1096 * ReplaceDeviateStatement,..) and create argument specific supports
1097 * (i.e. definitions) for each deviate type (very similarly like by
1100 for (final DeclaredStatement<?> child : deviateStatement.declaredSubstatements()) {
1101 if (child instanceof MustStatement) {
1102 emitMust((MustStatement) child);
1103 } else if (child instanceof DefaultStatement) {
1104 emitDefaultNode((DefaultStatement) child);
1105 } else if (child instanceof UniqueStatement) {
1106 emitUnique((UniqueStatement) child);
1107 } else if (child instanceof UnitsStatement) {
1108 emitUnitsNode((UnitsStatement) child);
1109 } else if (child instanceof TypeStatement) {
1110 emitType((TypeStatement) child);
1111 } else if (child instanceof MinElementsStatement) {
1112 emitMinElementsNode((MinElementsStatement) child);
1113 } else if (child instanceof MaxElementsStatement) {
1114 emitMaxElementsNode((MaxElementsStatement) child);
1115 } else if (child instanceof MandatoryStatement) {
1116 emitMandatoryNode((MandatoryStatement) child);
1117 } else if (child instanceof ConfigStatement) {
1118 emitConfigNode((ConfigStatement) child);
1119 } else if (child instanceof UnknownStatement) {
1120 emitUnknownStatementNode(child);
1123 super.writer.endNode();
1127 static class EffectiveSchemaContextEmitter extends SchemaContextEmitter {
1129 EffectiveSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
1130 final YangVersion yangVersion, final boolean emitInstantiated) {
1131 super(writer, extensions, yangVersion, emitInstantiated, true);
1134 void emitModule(final Module input) {
1135 super.writer.startModuleNode(input.getName());
1136 emitModuleHeader(input);
1137 emitLinkageNodes(input);
1138 emitMetaNodes(input);
1139 emitRevisionNodes(input);
1140 emitBodyNodes(input);
1141 super.writer.endNode();
1144 private void emitModuleHeader(final Module input) {
1145 emitYangVersionNode(input.getYangVersion());
1146 emitNamespace(input.getNamespace());
1147 emitPrefixNode(input.getPrefix());
1150 @SuppressWarnings("unused")
1151 private void emitSubmodule(final String input) {
1153 * FIXME: BUG-2444: Implement submodule export
1155 * submoduleHeaderNodes linkageNodes metaNodes revisionNodes
1156 * bodyNodes super.writer.endNode();
1160 @SuppressWarnings("unused")
1161 private void emitSubmoduleHeaderNodes(final Module input) {
1163 * FIXME: BUG-2444: Implement submodule headers properly
1165 * :yangVersionNode //Optional
1171 private void emitMetaNodes(final Module input) {
1172 emitOrganizationNode(input.getOrganization());
1173 emitContact(input.getContact());
1174 emitDescriptionNode(input.getDescription());
1175 emitReferenceNode(input.getReference());
1178 private void emitLinkageNodes(final Module input) {
1179 for (final ModuleImport importNode : input.getImports()) {
1180 emitImport(importNode);
1183 * FIXME: BUG-2444: Emit include statements
1187 private void emitRevisionNodes(final Module input) {
1189 * FIXME: BUG-2444: emit revisions properly, when parsed model will
1190 * provide enough information
1192 input.getRevision().ifPresent(this::emitRevision);
1195 private void emitBodyNodes(final Module input) {
1197 for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
1198 emitExtension(extension);
1200 for (final FeatureDefinition definition : input.getFeatures()) {
1201 emitFeature(definition);
1203 for (final IdentitySchemaNode identity : input.getIdentities()) {
1204 emitIdentity(identity);
1206 for (final Deviation deviation : input.getDeviations()) {
1207 emitDeviation(deviation);
1210 emitDataNodeContainer(input);
1212 for (final AugmentationSchemaNode augmentation : input.getAugmentations()) {
1213 emitAugment(augmentation);
1215 for (final RpcDefinition rpc : input.getRpcs()) {
1219 emitNotifications(input.getNotifications());
1222 private void emitDataNodeContainer(final DataNodeContainer input) {
1223 for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
1224 emitTypedefNode(typedef);
1226 for (final GroupingDefinition grouping : input.getGroupings()) {
1227 emitGrouping(grouping);
1229 for (final DataSchemaNode child : input.getChildNodes()) {
1230 emitDataSchemaNode(child);
1232 for (final UsesNode usesNode : input.getUses()) {
1233 emitUsesNode(usesNode);
1237 private void emitDataSchemaNode(final DataSchemaNode child) {
1238 if (!super.emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
1239 // We skip instantiated nodes.
1243 if (child instanceof ContainerSchemaNode) {
1244 emitContainer((ContainerSchemaNode) child);
1245 } else if (child instanceof LeafSchemaNode) {
1246 emitLeaf((LeafSchemaNode) child);
1247 } else if (child instanceof LeafListSchemaNode) {
1248 emitLeafList((LeafListSchemaNode) child);
1249 } else if (child instanceof ListSchemaNode) {
1250 emitList((ListSchemaNode) child);
1251 } else if (child instanceof ChoiceSchemaNode) {
1252 emitChoice((ChoiceSchemaNode) child);
1253 } else if (child instanceof AnyXmlSchemaNode) {
1254 emitAnyxml((AnyXmlSchemaNode) child);
1255 } else if (child instanceof AnyDataSchemaNode) {
1256 emitAnydata((AnyDataSchemaNode) child);
1258 throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
1262 private void emitYangVersionNode(final YangVersion input) {
1263 super.writer.startYangVersionNode(input.toString());
1264 super.writer.endNode();
1267 private void emitImport(final ModuleImport importNode) {
1268 super.writer.startImportNode(importNode.getModuleName());
1269 emitDescriptionNode(importNode.getDescription());
1270 emitReferenceNode(importNode.getReference());
1271 emitPrefixNode(importNode.getPrefix());
1273 importNode.getRevision().ifPresent(this::emitRevisionDateNode);
1274 super.writer.endNode();
1277 @SuppressWarnings("unused")
1278 private void emitInclude(final String input) {
1280 * FIXME: BUG-2444: Implement proper export of include statements
1281 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1284 * :revisionDateNode :super.writer.endNode();)
1288 private void emitNamespace(final URI uri) {
1289 super.writer.startNamespaceNode(uri);
1290 super.writer.endNode();
1294 private void emitPrefixNode(final String input) {
1295 super.writer.startPrefixNode(input);
1296 super.writer.endNode();
1300 @SuppressWarnings("unused")
1301 private void emitBelongsTo(final String input) {
1303 * FIXME: BUG-2444: Implement proper export of belongs-to statements
1304 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1307 * :super.writer.startBelongsToNode(IdentifierHelper.getIdentifier(
1311 * :prefixNode :super.writer.endNode();
1317 private void emitOrganizationNode(final String input) {
1318 if (!Strings.isNullOrEmpty(input)) {
1319 super.writer.startOrganizationNode(input);
1320 super.writer.endNode();
1324 private void emitContact(final String input) {
1325 if (!Strings.isNullOrEmpty(input)) {
1326 super.writer.startContactNode(input);
1327 super.writer.endNode();
1331 private void emitDescriptionNode(@Nullable final String input) {
1332 if (!Strings.isNullOrEmpty(input)) {
1333 super.writer.startDescriptionNode(input);
1334 super.writer.endNode();
1338 private void emitReferenceNode(@Nullable final String input) {
1339 if (!Strings.isNullOrEmpty(input)) {
1340 super.writer.startReferenceNode(input);
1341 super.writer.endNode();
1345 private void emitUnitsNode(@Nullable final String input) {
1346 if (!Strings.isNullOrEmpty(input)) {
1347 super.writer.startUnitsNode(input);
1348 super.writer.endNode();
1352 private void emitRevision(final Revision date) {
1354 super.writer.startRevisionNode(date);
1356 // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode
1357 // //FIXME: BUG-2444: Optional
1358 // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode
1359 // //FIXME: BUG-2444: Optional
1360 super.writer.endNode();
1364 private void emitRevisionDateNode(final Revision date) {
1365 super.writer.startRevisionDateNode(date);
1366 super.writer.endNode();
1369 private void emitExtension(final ExtensionDefinition extension) {
1370 super.writer.startExtensionNode(extension.getQName());
1371 emitArgument(extension.getArgument(), extension.isYinElement());
1372 emitStatusNode(extension.getStatus());
1373 emitDescriptionNode(extension.getDescription());
1374 emitReferenceNode(extension.getReference());
1375 emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
1376 super.writer.endNode();
1380 private void emitArgument(final @Nullable String input, final boolean yinElement) {
1381 if (input != null) {
1382 super.writer.startArgumentNode(input);
1383 emitYinElement(yinElement);
1384 super.writer.endNode();
1389 private void emitYinElement(final boolean yinElement) {
1390 super.writer.startYinElementNode(yinElement);
1391 super.writer.endNode();
1395 private void emitIdentity(final IdentitySchemaNode identity) {
1396 super.writer.startIdentityNode(identity.getQName());
1397 emitBaseIdentities(identity.getBaseIdentities());
1398 emitStatusNode(identity.getStatus());
1399 emitDescriptionNode(identity.getDescription());
1400 emitReferenceNode(identity.getReference());
1401 super.writer.endNode();
1404 private void emitBaseIdentities(final Set<IdentitySchemaNode> identities) {
1405 for (final IdentitySchemaNode identitySchemaNode : identities) {
1406 emitBase(identitySchemaNode.getQName());
1410 private void emitBase(final QName qName) {
1411 super.writer.startBaseNode(qName);
1412 super.writer.endNode();
1415 private void emitFeature(final FeatureDefinition definition) {
1416 super.writer.startFeatureNode(definition.getQName());
1418 // FIXME: BUG-2444: FIXME: BUG-2444: Expose ifFeature
1419 // *(ifFeatureNode )
1420 emitStatusNode(definition.getStatus());
1421 emitDescriptionNode(definition.getDescription());
1422 emitReferenceNode(definition.getReference());
1423 super.writer.endNode();
1427 @SuppressWarnings("unused")
1428 private void emitIfFeature(final String input) {
1430 * FIXME: BUG-2444: Implement proper export of include statements
1431 * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
1436 private void emitTypedefNode(final TypeDefinition<?> typedef) {
1437 super.writer.startTypedefNode(typedef.getQName());
1438 // Differentiate between derived type and existing type
1440 emitTypeNodeDerived(typedef);
1441 emitUnitsNode(typedef.getUnits());
1442 emitDefaultNode(typedef.getDefaultValue());
1443 emitStatusNode(typedef.getStatus());
1444 emitDescriptionNode(typedef.getDescription());
1445 emitReferenceNode(typedef.getReference());
1446 emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
1447 super.writer.endNode();
1451 private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
1452 final SchemaPath path = subtype.getPath();
1453 if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
1454 emitTypeNodeDerived(subtype);
1456 emitTypeNodeReferenced(subtype);
1460 private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
1461 super.writer.startTypeNode(typeDefinition.getQName());
1462 super.writer.endNode();
1466 private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
1467 final TypeDefinition<?> b = typeDefinition.getBaseType();
1468 final TypeDefinition<?> baseType = b == null ? typeDefinition : b;
1469 super.writer.startTypeNode(baseType.getQName());
1470 emitTypeBodyNodes(typeDefinition);
1471 super.writer.endNode();
1475 private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
1476 if (typeDef instanceof UnsignedIntegerTypeDefinition) {
1477 emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
1478 } else if (typeDef instanceof IntegerTypeDefinition) {
1479 emitIntegerSpefication((IntegerTypeDefinition) typeDef);
1480 } else if (typeDef instanceof DecimalTypeDefinition) {
1481 emitDecimal64Specification((DecimalTypeDefinition) typeDef);
1482 } else if (typeDef instanceof StringTypeDefinition) {
1483 emitStringRestrictions((StringTypeDefinition) typeDef);
1484 } else if (typeDef instanceof EnumTypeDefinition) {
1485 emitEnumSpecification((EnumTypeDefinition) typeDef);
1486 } else if (typeDef instanceof LeafrefTypeDefinition) {
1487 emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
1488 } else if (typeDef instanceof IdentityrefTypeDefinition) {
1489 emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
1490 } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
1491 emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
1492 } else if (typeDef instanceof BitsTypeDefinition) {
1493 emitBitsSpecification((BitsTypeDefinition) typeDef);
1494 } else if (typeDef instanceof UnionTypeDefinition) {
1495 emitUnionSpecification((UnionTypeDefinition) typeDef);
1496 } else if (typeDef instanceof BinaryTypeDefinition) {
1497 ((BinaryTypeDefinition) typeDef).getLengthConstraint().ifPresent(this::emitLength);
1498 } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
1501 throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
1505 private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
1506 emitRangeNodeOptional(typeDef.getRangeConstraints());
1509 private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
1510 emitRangeNodeOptional(typeDef.getRangeConstraints());
1514 private void emitRangeNodeOptional(final List<RangeConstraint> list) {
1515 // FIXME: BUG-2444: Wrong decomposition in API, should be
1517 // which contains ranges.
1518 if (!list.isEmpty()) {
1519 super.writer.startRangeNode(toRangeString(list));
1520 final RangeConstraint first = list.iterator().next();
1521 emitErrorMessageNode(first.getErrorMessage());
1522 emitErrorAppTagNode(first.getErrorAppTag());
1523 emitDescriptionNode(first.getDescription());
1524 emitReferenceNode(first.getReference());
1525 super.writer.endNode();
1530 private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
1531 emitFranctionDigitsNode(typeDefinition.getFractionDigits());
1532 emitRangeNodeOptional(typeDefinition.getRangeConstraints());
1536 private void emitFranctionDigitsNode(final Integer fractionDigits) {
1537 super.writer.startFractionDigitsNode(fractionDigits);
1538 super.writer.endNode();
1541 private void emitStringRestrictions(final StringTypeDefinition typeDef) {
1542 typeDef.getLengthConstraint().ifPresent(this::emitLength);
1544 for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
1545 emitPatternNode(pattern);
1549 private void emitLength(final LengthConstraint constraint) {
1550 super.writer.startLengthNode(toLengthString(constraint.getAllowedRanges()));
1551 emitErrorMessageNode(constraint.getErrorMessage());
1552 emitErrorAppTagNode(constraint.getErrorAppTag());
1553 emitDescriptionNode(constraint.getDescription());
1554 emitReferenceNode(constraint.getReference());
1555 super.writer.endNode();
1558 private static String toLengthString(final RangeSet<Integer> ranges) {
1559 final Iterator<Range<Integer>> it = ranges.asRanges().iterator();
1560 if (!it.hasNext()) {
1564 final StringBuilder sb = new StringBuilder();
1567 final Range<Integer> current = it.next();
1568 haveNext = it.hasNext();
1569 appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
1572 return sb.toString();
1575 private static String toRangeString(final List<RangeConstraint> list) {
1576 final Iterator<RangeConstraint> it = list.iterator();
1577 if (!it.hasNext()) {
1581 final StringBuilder sb = new StringBuilder();
1584 final RangeConstraint current = it.next();
1585 haveNext = it.hasNext();
1586 appendRange(sb, current.getMin(), current.getMax(), haveNext);
1589 return sb.toString();
1592 private static void appendRange(final StringBuilder sb, final Number min, final Number max,
1593 final boolean haveNext) {
1595 if (!min.equals(max)) {
1604 private void emitPatternNode(final PatternConstraint pattern) {
1605 super.writer.startPatternNode(pattern.getRawRegularExpression());
1606 // FIXME: BUG-2444: Optional
1607 emitErrorMessageNode(pattern.getErrorMessage());
1608 // FIXME: BUG-2444: Optional
1609 emitErrorAppTagNode(pattern.getErrorAppTag());
1610 emitDescriptionNode(pattern.getDescription());
1611 emitModifier(pattern.getModifier());
1612 super.writer.endNode();
1615 private void emitModifier(final ModifierKind modifier) {
1616 if (modifier != null) {
1617 super.writer.startModifierNode(modifier);
1618 super.writer.endNode();
1622 private void emitDefaultNodes(final Collection<String> defaults) {
1623 for (final String defaultValue : defaults) {
1624 emitDefaultNode(defaultValue);
1628 private void emitDefaultNode(@Nullable final Object object) {
1629 if (object != null) {
1630 super.writer.startDefaultNode(object.toString());
1631 super.writer.endNode();
1635 private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
1636 for (final EnumPair enumValue : typeDefinition.getValues()) {
1637 emitEnumNode(enumValue);
1641 private void emitEnumNode(final EnumPair enumValue) {
1642 super.writer.startEnumNode(enumValue.getName());
1643 emitValueNode(enumValue.getValue());
1644 emitStatusNode(enumValue.getStatus());
1645 emitDescriptionNode(enumValue.getDescription());
1646 emitReferenceNode(enumValue.getReference());
1647 super.writer.endNode();
1650 private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
1651 emitPathNode(typeDefinition.getPathStatement());
1652 if (YangVersion.VERSION_1_1 == super.yangVersion) {
1653 emitRequireInstanceNode(typeDefinition.requireInstance());
1657 private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
1658 super.writer.startPathNode(revisionAwareXPath);
1659 super.writer.endNode();
1662 private void emitRequireInstanceNode(final boolean require) {
1663 super.writer.startRequireInstanceNode(require);
1664 super.writer.endNode();
1667 private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
1668 emitRequireInstanceNode(typeDefinition.requireInstance());
1671 private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
1672 emitBaseIdentities(typeDefinition.getIdentities());
1675 private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
1676 for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
1677 // FIXME: BUG-2444: What if we have locally modified types here?
1678 // is solution to look-up in schema path?
1679 emitTypeNode(typeDefinition.getPath(), subtype);
1683 private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
1684 for (final Bit bit : typeDefinition.getBits()) {
1689 private void emitBit(final Bit bit) {
1690 super.writer.startBitNode(bit.getName());
1691 emitPositionNode(bit.getPosition());
1692 emitStatusNode(bit.getStatus());
1693 emitDescriptionNode(bit.getDescription());
1694 emitReferenceNode(bit.getReference());
1695 super.writer.endNode();
1698 private void emitPositionNode(@Nullable final Long position) {
1699 if (position != null) {
1700 super.writer.startPositionNode(UnsignedInteger.valueOf(position));
1701 super.writer.endNode();
1705 private void emitStatusNode(@Nullable final Status status) {
1706 if (status != null) {
1707 super.writer.startStatusNode(status);
1708 super.writer.endNode();
1712 private void emitConfigNode(final boolean config) {
1713 super.writer.startConfigNode(config);
1714 super.writer.endNode();
1717 private void emitMandatoryNode(final boolean mandatory) {
1718 super.writer.startMandatoryNode(mandatory);
1719 super.writer.endNode();
1722 private void emitPresenceNode(final boolean presence) {
1723 super.writer.startPresenceNode(presence);
1724 super.writer.endNode();
1727 private void emitOrderedBy(final boolean userOrdered) {
1729 super.writer.startOrderedByNode("user");
1731 super.writer.startOrderedByNode("system");
1733 super.writer.endNode();
1736 private void emitMust(@Nullable final MustDefinition mustCondition) {
1737 if (mustCondition != null && mustCondition.getXpath() != null) {
1738 super.writer.startMustNode(mustCondition.getXpath());
1739 emitErrorMessageNode(mustCondition.getErrorMessage());
1740 emitErrorAppTagNode(mustCondition.getErrorAppTag());
1741 emitDescriptionNode(mustCondition.getDescription());
1742 emitReferenceNode(mustCondition.getReference());
1743 super.writer.endNode();
1748 private void emitErrorMessageNode(@Nullable final String input) {
1749 if (input != null && !input.isEmpty()) {
1750 super.writer.startErrorMessageNode(input);
1751 super.writer.endNode();
1755 private void emitErrorAppTagNode(final String input) {
1756 if (input != null && !input.isEmpty()) {
1757 super.writer.startErrorAppTagNode(input);
1758 super.writer.endNode();
1762 private void emitMinElementsNode(final Integer min) {
1764 super.writer.startMinElementsNode(min);
1765 super.writer.endNode();
1769 private void emitMaxElementsNode(final Integer max) {
1771 super.writer.startMaxElementsNode(max);
1772 super.writer.endNode();
1776 private void emitValueNode(@Nullable final Integer value) {
1777 if (value != null) {
1778 super.writer.startValueNode(value);
1779 super.writer.endNode();
1783 private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
1784 emitStatusNode(input.getStatus());
1785 emitDescriptionNode(input.getDescription());
1786 emitReferenceNode(input.getReference());
1789 private void emitGrouping(final GroupingDefinition grouping) {
1790 super.writer.startGroupingNode(grouping.getQName());
1791 emitDocumentedNode(grouping);
1792 emitDataNodeContainer(grouping);
1793 emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
1794 emitNotifications(grouping.getNotifications());
1795 emitActions(grouping.getActions());
1796 super.writer.endNode();
1800 private void emitContainer(final ContainerSchemaNode child) {
1801 super.writer.startContainerNode(child.getQName());
1802 emitConstraints(child.getConstraints());
1803 // FIXME: BUG-2444: whenNode //:Optional
1804 // FIXME: BUG-2444: *(ifFeatureNode )
1805 emitPresenceNode(child.isPresenceContainer());
1806 emitConfigNode(child.isConfiguration());
1807 emitDocumentedNode(child);
1808 emitDataNodeContainer(child);
1809 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1810 emitNotifications(child.getNotifications());
1811 emitActions(child.getActions());
1812 super.writer.endNode();
1816 private void emitConstraints(final ConstraintDefinition constraints) {
1817 constraints.getWhenCondition().ifPresent(this::emitWhen);
1818 for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
1819 emitMust(mustCondition);
1823 private void emitLeaf(final LeafSchemaNode child) {
1824 super.writer.startLeafNode(child.getQName());
1825 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1826 // FIXME: BUG-2444: *(ifFeatureNode )
1827 emitTypeNode(child.getPath(), child.getType());
1828 emitUnitsNode(child.getUnits());
1829 emitMustNodes(child.getConstraints().getMustConstraints());
1830 emitDefaultNode(child.getDefault());
1831 emitConfigNode(child.isConfiguration());
1832 emitMandatoryNode(child.getConstraints().isMandatory());
1833 emitDocumentedNode(child);
1834 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1835 super.writer.endNode();
1839 private void emitLeafList(final LeafListSchemaNode child) {
1840 super.writer.startLeafListNode(child.getQName());
1842 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1843 // FIXME: BUG-2444: *(ifFeatureNode )
1844 emitTypeNode(child.getPath(), child.getType());
1845 emitUnitsNode(child.getType().getUnits());
1846 // FIXME: BUG-2444: unitsNode /Optional
1847 emitMustNodes(child.getConstraints().getMustConstraints());
1848 emitConfigNode(child.isConfiguration());
1849 emitDefaultNodes(child.getDefaults());
1850 emitMinElementsNode(child.getConstraints().getMinElements());
1851 emitMaxElementsNode(child.getConstraints().getMaxElements());
1852 emitOrderedBy(child.isUserOrdered());
1853 emitDocumentedNode(child);
1854 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1855 super.writer.endNode();
1859 private void emitList(final ListSchemaNode child) {
1860 super.writer.startListNode(child.getQName());
1861 child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1863 // FIXME: BUG-2444: *(ifFeatureNode )
1864 emitMustNodes(child.getConstraints().getMustConstraints());
1865 emitKey(child.getKeyDefinition());
1866 emitUniqueConstraints(child.getUniqueConstraints());
1867 emitConfigNode(child.isConfiguration());
1868 emitMinElementsNode(child.getConstraints().getMinElements());
1869 emitMaxElementsNode(child.getConstraints().getMaxElements());
1870 emitOrderedBy(child.isUserOrdered());
1871 emitDocumentedNode(child);
1872 emitDataNodeContainer(child);
1873 emitUnknownStatementNodes(child.getUnknownSchemaNodes());
1874 emitNotifications(child.getNotifications());
1875 emitActions(child.getActions());
1876 super.writer.endNode();
1880 private void emitMustNodes(final Set<MustDefinition> mustConstraints) {
1881 for (final MustDefinition must : mustConstraints) {
1886 private void emitKey(final List<QName> keyList) {
1887 if (keyList != null && !keyList.isEmpty()) {
1888 super.writer.startKeyNode(keyList);
1889 super.writer.endNode();
1893 private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
1894 for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
1895 emitUnique(uniqueConstraint);
1899 private void emitUnique(final UniqueConstraint uniqueConstraint) {
1900 super.writer.startUniqueNode(uniqueConstraint);
1901 super.writer.endNode();
1904 private void emitChoice(final ChoiceSchemaNode choice) {
1905 super.writer.startChoiceNode(choice.getQName());
1906 choice.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1907 // FIXME: BUG-2444: *(ifFeatureNode )
1908 // FIXME: BUG-2444: defaultNode //Optional
1909 emitConfigNode(choice.isConfiguration());
1910 emitMandatoryNode(choice.getConstraints().isMandatory());
1911 emitDocumentedNode(choice);
1912 for (final ChoiceCaseNode caze : choice.getCases()) {
1913 // TODO: emit short case?
1916 emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
1917 super.writer.endNode();
1920 private void emitCaseNode(final ChoiceCaseNode caze) {
1921 if (!super.emitInstantiated && caze.isAugmenting()) {
1924 super.writer.startCaseNode(caze.getQName());
1925 caze.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1926 // FIXME: BUG-2444: *(ifFeatureNode )
1927 emitDocumentedNode(caze);
1928 emitDataNodeContainer(caze);
1929 emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
1930 super.writer.endNode();
1934 private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
1935 super.writer.startAnyxmlNode(anyxml.getQName());
1936 emitBodyOfDataSchemaNode(anyxml);
1937 super.writer.endNode();
1940 private void emitAnydata(final AnyDataSchemaNode anydata) {
1941 super.writer.startAnydataNode(anydata.getQName());
1942 emitBodyOfDataSchemaNode(anydata);
1943 super.writer.endNode();
1946 private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
1947 dataSchemaNode.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
1948 // FIXME: BUG-2444: *(ifFeatureNode )
1949 emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
1950 emitConfigNode(dataSchemaNode.isConfiguration());
1951 emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
1952 emitDocumentedNode(dataSchemaNode);
1953 emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
1956 private void emitUsesNode(final UsesNode usesNode) {
1957 if (super.emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
1958 super.writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
1960 * FIXME: BUG-2444: whenNode / *(ifFeatureNode ) statusNode //
1961 * Optional F : descriptionNode // Optional referenceNode //
1964 for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
1967 for (final AugmentationSchemaNode aug : usesNode.getAugmentations()) {
1968 emitUsesAugmentNode(aug);
1970 super.writer.endNode();
1974 private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
1975 final SchemaPath path = refine.getKey();
1976 final SchemaNode value = refine.getValue();
1977 super.writer.startRefineNode(path);
1979 if (value instanceof LeafSchemaNode) {
1980 emitRefineLeafNodes((LeafSchemaNode) value);
1981 } else if (value instanceof LeafListSchemaNode) {
1982 emitRefineLeafListNodes((LeafListSchemaNode) value);
1983 } else if (value instanceof ListSchemaNode) {
1984 emitRefineListNodes((ListSchemaNode) value);
1985 } else if (value instanceof ChoiceSchemaNode) {
1986 emitRefineChoiceNodes((ChoiceSchemaNode) value);
1987 } else if (value instanceof ChoiceCaseNode) {
1988 emitRefineCaseNodes((ChoiceCaseNode) value);
1989 } else if (value instanceof ContainerSchemaNode) {
1990 emitRefineContainerNodes((ContainerSchemaNode) value);
1991 } else if (value instanceof AnyXmlSchemaNode) {
1992 emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
1994 super.writer.endNode();
1998 private static <T extends SchemaNode> T getOriginalChecked(final T value) {
1999 final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
2000 Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
2001 @SuppressWarnings("unchecked")
2002 final T ret = (T) original.get();
2006 private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
2007 if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
2008 emitDescriptionNode(value.getDescription());
2010 if (Objects.deepEquals(original.getReference(), value.getReference())) {
2011 emitReferenceNode(value.getReference());
2015 private void emitRefineContainerNodes(final ContainerSchemaNode value) {
2016 final ContainerSchemaNode original = getOriginalChecked(value);
2018 // emitMustNodes(child.getConstraints().getMustConstraints());
2019 if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
2020 emitPresenceNode(value.isPresenceContainer());
2022 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2023 emitConfigNode(value.isConfiguration());
2025 emitDocumentedNodeRefine(original, value);
2029 private void emitRefineLeafNodes(final LeafSchemaNode value) {
2030 final LeafSchemaNode original = getOriginalChecked(value);
2032 // emitMustNodes(child.getConstraints().getMustConstraints());
2033 if (Objects.deepEquals(original.getDefault(), value.getDefault())) {
2034 emitDefaultNode(value.getDefault());
2036 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2037 emitConfigNode(value.isConfiguration());
2039 emitDocumentedNodeRefine(original, value);
2040 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2041 emitMandatoryNode(value.getConstraints().isMandatory());
2046 private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
2047 final LeafListSchemaNode original = getOriginalChecked(value);
2049 // emitMustNodes(child.getConstraints().getMustConstraints());
2050 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2051 emitConfigNode(value.isConfiguration());
2053 if (Objects.deepEquals(original.getConstraints().getMinElements(),
2054 value.getConstraints().getMinElements())) {
2055 emitMinElementsNode(value.getConstraints().getMinElements());
2057 if (Objects.deepEquals(original.getConstraints().getMaxElements(),
2058 value.getConstraints().getMaxElements())) {
2059 emitMaxElementsNode(value.getConstraints().getMaxElements());
2061 emitDocumentedNodeRefine(original, value);
2065 private void emitRefineListNodes(final ListSchemaNode value) {
2066 final ListSchemaNode original = getOriginalChecked(value);
2068 // emitMustNodes(child.getConstraints().getMustConstraints());
2069 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2070 emitConfigNode(value.isConfiguration());
2072 if (Objects.deepEquals(original.getConstraints().getMinElements(),
2073 value.getConstraints().getMinElements())) {
2074 emitMinElementsNode(value.getConstraints().getMinElements());
2076 if (Objects.deepEquals(original.getConstraints().getMaxElements(),
2077 value.getConstraints().getMaxElements())) {
2078 emitMaxElementsNode(value.getConstraints().getMaxElements());
2080 emitDocumentedNodeRefine(original, value);
2084 private void emitRefineChoiceNodes(final ChoiceSchemaNode value) {
2085 final ChoiceSchemaNode original = getOriginalChecked(value);
2087 // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
2088 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2089 emitConfigNode(value.isConfiguration());
2091 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2092 emitMandatoryNode(value.getConstraints().isMandatory());
2094 emitDocumentedNodeRefine(original, value);
2098 private void emitRefineCaseNodes(final ChoiceCaseNode value) {
2099 final ChoiceCaseNode original = getOriginalChecked(value);
2100 emitDocumentedNodeRefine(original, value);
2104 private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
2105 final AnyXmlSchemaNode original = getOriginalChecked(value);
2108 // emitMustNodes(child.getConstraints().getMustConstraints());
2109 if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
2110 emitConfigNode(value.isConfiguration());
2112 if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
2113 emitMandatoryNode(value.getConstraints().isMandatory());
2115 emitDocumentedNodeRefine(original, value);
2119 private void emitUsesAugmentNode(final AugmentationSchemaNode aug) {
2121 * differs only in location in schema, otherwise currently (as of
2122 * RFC6020) it is same, so we could freely reuse path.
2127 private void emitAugment(final AugmentationSchemaNode augmentation) {
2128 super.writer.startAugmentNode(augmentation.getTargetPath());
2129 // FIXME: BUG-2444: whenNode //Optional
2130 // FIXME: BUG-2444: *(ifFeatureNode )
2132 emitStatusNode(augmentation.getStatus());
2133 emitDescriptionNode(augmentation.getDescription());
2134 emitReferenceNode(augmentation.getReference());
2135 for (final UsesNode uses : augmentation.getUses()) {
2139 for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
2140 if (childNode instanceof ChoiceCaseNode) {
2141 emitCaseNode((ChoiceCaseNode) childNode);
2143 emitDataSchemaNode(childNode);
2146 emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
2147 emitNotifications(augmentation.getNotifications());
2148 emitActions(augmentation.getActions());
2149 super.writer.endNode();
2152 private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
2153 for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
2154 if (!unknonwnNode.isAddedByAugmentation() && !unknonwnNode.isAddedByUses()) {
2155 emitUnknownStatementNode(unknonwnNode);
2160 private void emitUnknownStatementNode(final UnknownSchemaNode node) {
2161 final StatementDefinition def = getStatementChecked(node.getNodeType());
2162 if (def.getArgumentName() == null) {
2163 super.writer.startUnknownNode(def);
2165 super.writer.startUnknownNode(def, node.getNodeParameter());
2167 emitUnknownStatementNodes(node.getUnknownSchemaNodes());
2168 super.writer.endNode();
2171 private StatementDefinition getStatementChecked(final QName nodeType) {
2172 final StatementDefinition ret = super.extensions.get(nodeType);
2173 Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
2177 private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
2178 if (revisionAwareXPath != null) {
2179 super.writer.startWhenNode(revisionAwareXPath);
2180 super.writer.endNode();
2182 // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
2183 // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
2184 // FIXME: BUG-2444: super.writer.endNode();)
2188 private void emitRpc(final RpcDefinition rpc) {
2189 super.writer.startRpcNode(rpc.getQName());
2190 emitOperationBody(rpc);
2191 super.writer.endNode();
2194 private void emitOperationBody(final OperationDefinition rpc) {
2195 // FIXME: BUG-2444: *(ifFeatureNode )
2196 emitStatusNode(rpc.getStatus());
2197 emitDescriptionNode(rpc.getDescription());
2198 emitReferenceNode(rpc.getReference());
2200 for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
2201 emitTypedefNode(typedef);
2203 for (final GroupingDefinition grouping : rpc.getGroupings()) {
2204 emitGrouping(grouping);
2206 emitInput(rpc.getInput());
2207 emitOutput(rpc.getOutput());
2208 emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
2211 private void emitActions(final Set<ActionDefinition> actions) {
2212 for (final ActionDefinition actionDefinition : actions) {
2213 emitAction(actionDefinition);
2217 private void emitAction(final ActionDefinition action) {
2218 if (!super.emitInstantiated && (action.isAddedByUses() || action.isAugmenting())) {
2219 // We skip instantiated nodes.
2222 super.writer.startActionNode(action.getQName());
2223 emitOperationBody(action);
2224 super.writer.endNode();
2227 private void emitInput(@Nonnull final ContainerSchemaNode input) {
2228 if (isExplicitStatement(input)) {
2229 super.writer.startInputNode();
2230 emitConstraints(input.getConstraints());
2231 emitDataNodeContainer(input);
2232 emitUnknownStatementNodes(input.getUnknownSchemaNodes());
2233 super.writer.endNode();
2238 private void emitOutput(@Nonnull final ContainerSchemaNode output) {
2239 if (isExplicitStatement(output)) {
2240 super.writer.startOutputNode();
2241 emitConstraints(output.getConstraints());
2242 emitDataNodeContainer(output);
2243 emitUnknownStatementNodes(output.getUnknownSchemaNodes());
2244 super.writer.endNode();
2248 private static boolean isExplicitStatement(final ContainerSchemaNode node) {
2249 return node instanceof EffectiveStatement && ((EffectiveStatement<?, ?>) node).getDeclared()
2250 .getStatementSource() == StatementSource.DECLARATION;
2253 private void emitNotifications(final Set<NotificationDefinition> notifications) {
2254 for (final NotificationDefinition notification : notifications) {
2255 emitNotificationNode(notification);
2259 private void emitNotificationNode(final NotificationDefinition notification) {
2260 if (!super.emitInstantiated && (notification.isAddedByUses() || notification.isAugmenting())) {
2261 // We skip instantiated nodes.
2265 super.writer.startNotificationNode(notification.getQName());
2266 // FIXME: BUG-2444: *(ifFeatureNode )
2267 emitConstraints(notification.getConstraints());
2268 emitDocumentedNode(notification);
2269 emitDataNodeContainer(notification);
2270 emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
2271 super.writer.endNode();
2275 private void emitDeviation(final Deviation deviation) {
2277 * FIXME: BUG-2444: Deviation is not modeled properly and we are
2278 * loosing lot of information in order to export it properly
2280 * super.writer.startDeviationNode(deviation.getTargetPath());
2282 * :descriptionNode //:Optional
2285 * emitReferenceNode(deviation.getReference());
2286 * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
2287 * :deviateDeleteNode)) :super.writer.endNode();