X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Fstmt%2FEffectiveStatementMixins.java;h=3eb78f0488bd4a1d2a9dba1b1488f9ae7b061c3c;hb=62c350eff478deeaa90ab0304cdc9c3623c01c83;hp=359ccac359ecef11c9a64e0930de5f30f7a614d5;hpb=228a4c87ff818c52410b1e449fd1587b16aaf4e1;p=yangtools.git diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java index 359ccac359..3eb78f0488 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java @@ -7,16 +7,17 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; -import static com.google.common.base.Verify.verify; - import com.google.common.annotations.Beta; import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import java.util.Collection; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.concepts.Mutable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ActionDefinition; @@ -24,20 +25,22 @@ import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer; import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition; +import org.opendaylight.yangtools.yang.model.api.ContainerLike; import org.opendaylight.yangtools.yang.model.api.CopyableNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode; import org.opendaylight.yangtools.yang.model.api.DocumentedNode; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.InputSchemaNode; import org.opendaylight.yangtools.yang.model.api.MandatoryAware; import org.opendaylight.yangtools.yang.model.api.MustConstraintAware; import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer; import org.opendaylight.yangtools.yang.model.api.OperationDefinition; -import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.OutputSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; @@ -47,13 +50,18 @@ import org.opendaylight.yangtools.yang.model.api.WhenConditionAware; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.WhenEffectiveStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder; +import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; -import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound; /** * Mix-in interfaces providing services required by SchemaNode et al. These interfaces provide implementations, or @@ -64,7 +72,7 @@ public final class EffectiveStatementMixins { // Marker interface requiring all mixins to be derived from EffectiveStatement. private interface Mixin> extends EffectiveStatement { @SuppressWarnings("unchecked") - default Collection filterEffectiveStatements(final Class type) { + default @NonNull Collection filterEffectiveStatements(final Class type) { // Yeah, this is not nice, but saves one transformation return (Collection) Collections2.filter(effectiveSubstatements(), type::isInstance); } @@ -93,6 +101,7 @@ public final class EffectiveStatementMixins { public interface AddedByUsesMixin> extends EffectiveStatementWithFlags, AddedByUsesAware { @Override + @Deprecated default boolean isAddedByUses() { return (flags() & FlagsBuilder.ADDED_BY_USES) != 0; } @@ -134,7 +143,7 @@ public final class EffectiveStatementMixins { */ public interface MustConstraintMixin> extends Mixin, MustConstraintAware { @Override - default Collection getMustConstraints() { + default Collection getMustConstraints() { return filterEffectiveStatements(MustDefinition.class); } } @@ -147,6 +156,7 @@ public final class EffectiveStatementMixins { */ public interface CopyableMixin> extends AddedByUsesMixin, CopyableNode { @Override + @Deprecated default boolean isAugmenting() { return (flags() & FlagsBuilder.AUGMENTING) != 0; } @@ -189,8 +199,18 @@ public final class EffectiveStatementMixins { public interface DataSchemaNodeMixin> extends DataSchemaNode, CopyableMixin, SchemaNodeMixin, WhenConditionMixin { @Override - default boolean isConfiguration() { - return (flags() & FlagsBuilder.CONFIGURATION) != 0; + default Optional effectiveConfig() { + final int fl = flags() & FlagsBuilder.MASK_CONFIG; + switch (fl) { + case FlagsBuilder.CONFIG_FALSE: + return Optional.of(Boolean.FALSE); + case FlagsBuilder.CONFIG_TRUE: + return Optional.of(Boolean.TRUE); + case FlagsBuilder.CONFIG_UNDEF: + return Optional.empty(); + default: + throw new IllegalStateException("Unhandled effective config flags " + fl); + } } } @@ -242,6 +262,25 @@ public final class EffectiveStatementMixins { } } + /** + * Bridge between {@link EffectiveStatementWithFlags} and {@link ConstraintMetaDefinition}. + * + * @param Argument type ({@link Void} if statement does not have argument.) + * @param Class representing declared version of this statement. + */ + public interface ConstraintMetaDefinitionMixin> extends DocumentedNodeMixin, + ConstraintMetaDefinition { + @Override + default Optional getErrorAppTag() { + return findFirstEffectiveSubstatementArgument(ErrorAppTagEffectiveStatement.class); + } + + @Override + default Optional getErrorMessage() { + return findFirstEffectiveSubstatementArgument(ErrorMessageEffectiveStatement.class); + } + } + /** * Bridge between {@link EffectiveStatementWithFlags} and {@link MandatoryAware}. * @@ -282,6 +321,21 @@ public final class EffectiveStatementMixins { } } + /** + * Bridge between {@link EffectiveStatementWithFlags} and {@link UnknownSchemaNode}. + * + * @param Argument type ({@link Void} if statement does not have argument.) + * @param Class representing declared version of this statement. + */ + public interface UnknownSchemaNodeMixin> + extends SchemaNodeMixin, CopyableMixin, UnknownSchemaNode { + + @Override + default String getNodeParameter() { + return Strings.nullToEmpty(getDeclared().rawArgument()); + } + } + /** * Bridge between {@link EffectiveStatementWithFlags} and {@code ordered-by} statement. * @@ -303,7 +357,7 @@ public final class EffectiveStatementMixins { */ public interface WhenConditionMixin> extends Mixin, WhenConditionAware { @Override - default Optional getWhenCondition() { + default Optional getWhenCondition() { return findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class); } } @@ -314,17 +368,12 @@ public final class EffectiveStatementMixins { * @param Class representing declared version of this statement. */ public interface OperationContainerMixin> - extends ContainerSchemaNode, DocumentedNodeMixin.WithStatus, DataNodeContainerMixin, + extends ContainerLike, DocumentedNodeMixin.WithStatus, DataNodeContainerMixin, MustConstraintMixin, WhenConditionMixin, AugmentationTargetMixin, - CopyableMixin { + SchemaNodeMixin, CopyableMixin { @Override default @NonNull QName argument() { - return getPath().getLastComponent(); - } - - @Override - default QName getQName() { - return argument(); + return getQName(); } @Override @@ -348,14 +397,8 @@ public final class EffectiveStatementMixins { } @Override - default boolean isConfiguration() { - return false; - } - - @Override - default boolean isPresenceContainer() { - // FIXME: this should not really be here - return false; + default Optional effectiveConfig() { + return Optional.empty(); } default String defaultToString() { @@ -373,12 +416,7 @@ public final class EffectiveStatementMixins { MandatoryMixin, MustConstraintMixin, WhenConditionMixin { @Override default @NonNull QName argument() { - return getPath().getLastComponent(); - } - - @Override - default QName getQName() { - return argument(); + return getQName(); } } @@ -391,32 +429,27 @@ public final class EffectiveStatementMixins { extends SchemaNodeMixin, OperationDefinition { @Override default @NonNull QName argument() { - return getPath().getLastComponent(); + return getQName(); } @Override - default QName getQName() { - return argument(); - } - - @Override - default Collection> getTypeDefinitions() { + default Collection> getTypeDefinitions() { return filterTypeDefinitions(this); } @Override - default Collection getGroupings() { + default Collection getGroupings() { return filterEffectiveStatements(GroupingDefinition.class); } @Override - default ContainerSchemaNode getInput() { - return findAsContainer(this, InputEffectiveStatement.class); + default InputSchemaNode getInput() { + return findAsContainer(this, InputEffectiveStatement.class, InputSchemaNode.class); } @Override - default ContainerSchemaNode getOutput() { - return findAsContainer(this, OutputEffectiveStatement.class); + default OutputSchemaNode getOutput() { + return findAsContainer(this, OutputEffectiveStatement.class, OutputSchemaNode.class); } } @@ -437,14 +470,13 @@ public final class EffectiveStatementMixins { @NonNullByDefault final class FlagsBuilder implements Mutable { - // We still have 24 flags remaining + // We still have 23 flags remaining static final int STATUS_CURRENT = 0x0001; static final int STATUS_DEPRECATED = 0x0002; static final int STATUS_OBSOLETE = 0x0003; static final int MASK_STATUS = 0x0003; - static final int CONFIGURATION = 0x0004; - static final int MANDATORY = 0x0008; + static final int MANDATORY = 0x0004; static final int AUGMENTING = 0x0010; static final int ADDED_BY_USES = 0x0020; @@ -453,32 +485,27 @@ public final class EffectiveStatementMixins { static final int USER_ORDERED = 0x0040; static final int PRESENCE = 0x0080; + static final int CONFIG_UNDEF = 0x0100; + static final int CONFIG_FALSE = 0x0200; + static final int CONFIG_TRUE = 0x0300; + static final int MASK_CONFIG = CONFIG_TRUE; + private int flags; - public FlagsBuilder setConfiguration(final boolean config) { - if (config) { - flags |= CONFIGURATION; + public FlagsBuilder setConfiguration(final @Nullable Boolean config) { + final int fl; + if (config != null) { + fl = config ? CONFIG_TRUE : CONFIG_FALSE; } else { - flags &= ~CONFIGURATION; + fl = CONFIG_UNDEF; } + flags = flags & ~MASK_CONFIG | fl; return this; } public FlagsBuilder setHistory(final CopyHistory history) { - int bits; - if (history.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) { - bits = AUGMENTING | ADDED_BY_USES; - } else { - bits = 0; - if (history.contains(CopyType.ADDED_BY_AUGMENTATION)) { - bits |= AUGMENTING; - } - if (history.contains(CopyType.ADDED_BY_USES)) { - bits |= ADDED_BY_USES; - } - } - - flags = flags & ~MASK_HISTORY | bits; + flags = flags & ~MASK_HISTORY + | (history.isAugmenting() ? AUGMENTING : 0) | (history.isAddedByUses() ? ADDED_BY_USES : 0); return this; } @@ -538,16 +565,22 @@ public final class EffectiveStatementMixins { private EffectiveStatementMixins() { } - static ContainerSchemaNode findAsContainer(final EffectiveStatement stmt, - final Class> type) { - final EffectiveStatement statement = stmt.findFirstEffectiveSubstatement(type).get(); - verify(statement instanceof ContainerSchemaNode, "Child statement %s is not a ContainerSchemaNode", - statement); - return (ContainerSchemaNode) statement; + static T findAsContainer(final EffectiveStatement stmt, + final Class> type, final Class target) { + return target.cast(stmt.findFirstEffectiveSubstatement(type).get()); } - static Collection> filterTypeDefinitions(final Mixin stmt) { + static Collection> filterTypeDefinitions(final Mixin stmt) { return Collections2.transform(stmt.filterEffectiveStatements(TypedefEffectiveStatement.class), TypedefEffectiveStatement::getTypeDefinition); } + + public static int historyAndStatusFlags(final CopyHistory history, + final ImmutableList> substatements) { + return new FlagsBuilder() + .setHistory(history) + .setStatus(AbstractStatementSupport.findFirstArgument(substatements, + StatusEffectiveStatement.class, Status.CURRENT)) + .toFlags(); + } }