From 954f358ee3688cb6f68a3ab84d78f55f71bc3efd Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 2 Jul 2020 13:37:42 +0200 Subject: [PATCH] Convert UsesStatementSupport to BaseQNameStatementSupport Uses statement is a bit more complicated in its effective form, hence we end up with four different implementations when we optimize for size. JIRA: YANGTOOLS-1065 Change-Id: I7f01ecd8277a042821cb5b37c0d9406a1e9204be Signed-off-by: Robert Varga --- .../api/stmt/UsesEffectiveStatement.java | 7 +- .../yang/model/api/stmt/UsesStatement.java | 7 ++ .../stmt/EffectiveStatementMixins.java | 2 +- .../EmptyLocalUsesEffectiveStatement.java | 78 ++++++++++++ ...ementImpl.java => EmptyUsesStatement.java} | 8 +- .../FullCopiedUsesEffectiveStatement.java | 48 ++++++++ .../RegularLocalUsesEffectiveStatement.java | 59 +++++++++ .../stmt/uses/RegularUsesStatement.java | 22 ++++ .../SimpleCopiedUsesEffectiveStatement.java | 85 +++++++++++++ .../stmt/uses/UsesEffectiveStatementImpl.java | 113 ------------------ .../stmt/uses/UsesStatementSupport.java | 86 +++++++++++-- 11 files changed, 388 insertions(+), 127 deletions(-) create mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyLocalUsesEffectiveStatement.java rename yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/{UsesStatementImpl.java => EmptyUsesStatement.java} (61%) create mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/FullCopiedUsesEffectiveStatement.java create mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularLocalUsesEffectiveStatement.java create mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularUsesStatement.java create mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/SimpleCopiedUsesEffectiveStatement.java delete mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesEffectiveStatementImpl.java diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesEffectiveStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesEffectiveStatement.java index 0f31ace6b4..d0a4950156 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesEffectiveStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesEffectiveStatement.java @@ -9,9 +9,14 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import com.google.common.annotations.Beta; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; @Beta public interface UsesEffectiveStatement extends EffectiveStatement { - + @Override + default StatementDefinition statementDefinition() { + return YangStmtMapping.USES; + } } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java index 4f6bd7b6ec..41399323f3 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java @@ -9,8 +9,15 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import java.util.Collection; import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; public interface UsesStatement extends DataDefinitionStatement { + @Override + default StatementDefinition statementDefinition() { + return YangStmtMapping.USES; + } + default @NonNull Collection getRefines() { return declaredSubstatements(RefineStatement.class); } 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 fef9424600..76c31701ed 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 @@ -67,7 +67,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); } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyLocalUsesEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyLocalUsesEffectiveStatement.java new file mode 100644 index 0000000000..d1d731bee9 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyLocalUsesEffectiveStatement.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableMap; +import java.util.Collection; +import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultArgument; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.CopyableMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DocumentedNodeMixin.WithStatus; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.WhenConditionMixin; + +/** + * Empty {@link UsesEffectiveStatement}, at its very simplest form. This is appropriate when all of these are true: + *
    + *
  • This statement takes effect in the same module as where it was declared, i.e. the arguments match
  • + *
  • It has no substatements
  • + *
+ * + *

+ * This provides minimum footprint, as we share the argument from the declared instance and just keep the flags and + * source grouping pointer. + */ +class EmptyLocalUsesEffectiveStatement extends DefaultArgument + implements UsesEffectiveStatement, UsesNode, CopyableMixin, + WhenConditionMixin, WithStatus { + private final @NonNull GroupingDefinition sourceGrouping; + private final int flags; + + EmptyLocalUsesEffectiveStatement(final UsesStatement declared, final GroupingDefinition sourceGrouping, + final int flags) { + super(declared); + this.sourceGrouping = requireNonNull(sourceGrouping); + this.flags = flags; + } + + @Override + public final GroupingDefinition getSourceGrouping() { + return sourceGrouping; + } + + @Override + public final int flags() { + return flags; + } + + @Override + public Collection getAugmentations() { + return filterEffectiveStatements(AugmentationSchemaNode.class); + } + + @Override + public Map getRefines() { + return ImmutableMap.of(); + } + + @Override + // FIXME: 6.0.0: remove this method + public final String toString() { + return "UsesEffectiveStatementImpl[sourceGrouping=" + sourceGrouping.getQName() + "]"; + } +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyUsesStatement.java similarity index 61% rename from yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementImpl.java rename to yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyUsesStatement.java index 0c302199c7..d9ced28fc6 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementImpl.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/EmptyUsesStatement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -9,11 +9,11 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithArgument; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -final class UsesStatementImpl extends AbstractDeclaredStatement implements UsesStatement { - UsesStatementImpl(final StmtContext context) { +final class EmptyUsesStatement extends WithArgument implements UsesStatement { + EmptyUsesStatement(final StmtContext context) { super(context); } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/FullCopiedUsesEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/FullCopiedUsesEffectiveStatement.java new file mode 100644 index 0000000000..00d64f78c9 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/FullCopiedUsesEffectiveStatement.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; + +import com.google.common.collect.ImmutableList; +import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; + +/** + * A full-blown instance of {@link UsesEffectiveStatement}. Used when the argument does not match the declared instance + * and we also have a refine substatement. + * + */ +final class FullCopiedUsesEffectiveStatement extends SimpleCopiedUsesEffectiveStatement { + private volatile Map refines; + + FullCopiedUsesEffectiveStatement(final UsesStatement declared, final QName argument, + final GroupingDefinition sourceGrouping, final int flags, + final ImmutableList> substatements) { + super(declared, argument, sourceGrouping, flags, substatements); + } + + @Override + public Map getRefines() { + final Map local; + return (local = refines) != null ? local : loadRefines(); + } + + private synchronized @NonNull Map loadRefines() { + Map local = refines; + if (local == null) { + refines = local = UsesStatementSupport.indexRefines(effectiveSubstatements()); + } + return local; + } +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularLocalUsesEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularLocalUsesEffectiveStatement.java new file mode 100644 index 0000000000..30066f0b62 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularLocalUsesEffectiveStatement.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; + +import com.google.common.collect.ImmutableList; +import java.util.Collection; +import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; + +/** + * An extension of {@link EmptyLocalUsesEffectiveStatement}, which adds substatements to the mix. Since this means we + * can also have refine statements, we keep a lazily-populated map of those. + */ +final class RegularLocalUsesEffectiveStatement extends EmptyLocalUsesEffectiveStatement { + private final Object substatements; + + private volatile Map refines; + + RegularLocalUsesEffectiveStatement(final UsesStatement declared, final GroupingDefinition sourceGrouping, + final int flags, final ImmutableList> substatements) { + super(declared, sourceGrouping, flags); + this.substatements = maskList(substatements); + } + + @Override + public ImmutableList> effectiveSubstatements() { + return unmaskList(substatements); + } + + @Override + public Collection getAugmentations() { + return filterEffectiveStatements(AugmentationSchemaNode.class); + } + + @Override + public Map getRefines() { + final Map local; + return (local = refines) != null ? local : loadRefines(); + } + + private synchronized @NonNull Map loadRefines() { + Map local = refines; + if (local == null) { + refines = local = UsesStatementSupport.indexRefines(effectiveSubstatements()); + } + return local; + } +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularUsesStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularUsesStatement.java new file mode 100644 index 0000000000..3dc70d58ad --- /dev/null +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/RegularUsesStatement.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; + +import com.google.common.collect.ImmutableList; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithArgument.WithSubstatements; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; + +final class RegularUsesStatement extends WithSubstatements implements UsesStatement { + RegularUsesStatement(final StmtContext context, + final ImmutableList> substatements) { + super(context, substatements); + } +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/SimpleCopiedUsesEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/SimpleCopiedUsesEffectiveStatement.java new file mode 100644 index 0000000000..0cec3b48a4 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/SimpleCopiedUsesEffectiveStatement.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.Collection; +import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultWithArgument; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.CopyableMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DocumentedNodeMixin.WithStatus; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.WhenConditionMixin; + +/** + * A simple case of a copied statement. The key difference here is that the argument does not match the declared + * argument -- i.e. the effective instance is in a different module. This also means that there is some history + * copy history attached. + * + *

+ * Since we have to keep the argument already, we perform a different field cut than in the local case and handle + * also substatements here. We do not handle further refines, though, as that requires yet another field, further + * growing instance size. That case is handled by {@link FullCopiedUsesEffectiveStatement}. + */ +class SimpleCopiedUsesEffectiveStatement extends DefaultWithArgument.WithSubstatements + implements UsesEffectiveStatement, UsesNode, CopyableMixin, + WhenConditionMixin, WithStatus { + private final @NonNull GroupingDefinition sourceGrouping; + private final int flags; + + SimpleCopiedUsesEffectiveStatement(final UsesStatement declared, final QName argument, + final GroupingDefinition sourceGrouping, final int flags, + final ImmutableList> substatements) { + super(declared, argument, substatements); + this.sourceGrouping = requireNonNull(sourceGrouping); + this.flags = flags; + } + + SimpleCopiedUsesEffectiveStatement(final UsesStatement declared, final QName argument, + final GroupingDefinition sourceGrouping, final int flags) { + this(declared, argument, sourceGrouping, flags, ImmutableList.of()); + } + + @Override + public final GroupingDefinition getSourceGrouping() { + return sourceGrouping; + } + + @Override + public final int flags() { + return flags; + } + + @Override + public final Collection getAugmentations() { + return filterEffectiveStatements(AugmentationSchemaNode.class); + } + + @Override + public Map getRefines() { + return ImmutableMap.of(); + } + + @Override + // FIXME: 6.0.0: remove this method + public final String toString() { + return "UsesEffectiveStatementImpl[sourceGrouping=" + sourceGrouping.getQName() + "]"; + } +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesEffectiveStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesEffectiveStatementImpl.java deleted file mode 100644 index 7a6e0a31e7..0000000000 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesEffectiveStatementImpl.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.opendaylight.yangtools.yang.model.api.UsesNode; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.GroupingEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; -import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.WhenEffectiveStatement; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveDocumentedNodeWithStatus; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.refine.RefineEffectiveStatementImpl; -import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace; -import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; - -final class UsesEffectiveStatementImpl extends AbstractEffectiveDocumentedNodeWithStatus - implements UsesEffectiveStatement, UsesNode { - private final @NonNull GroupingDefinition sourceGrouping; - private final boolean addedByUses; - private final @NonNull ImmutableMap refines; - private final @NonNull ImmutableSet augmentations; - private final @Nullable RevisionAwareXPath whenCondition; - - UsesEffectiveStatementImpl(final StmtContext ctx) { - super(ctx); - - // initGroupingPath - final StmtContext grpCtx = - ctx.getFromNamespace(GroupingNamespace.class, ctx.coerceStatementArgument()); - this.sourceGrouping = (GroupingDefinition) grpCtx.buildEffective(); - - // initCopyType - addedByUses = ctx.getCopyHistory().contains(CopyType.ADDED_BY_USES); - - // initSubstatementCollections - final Set augmentationsInit = new LinkedHashSet<>(); - final Map refinesInit = new LinkedHashMap<>(); - for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { - if (effectiveStatement instanceof AugmentationSchemaNode) { - final AugmentationSchemaNode augmentationSchema = (AugmentationSchemaNode) effectiveStatement; - augmentationsInit.add(augmentationSchema); - } - if (effectiveStatement instanceof RefineEffectiveStatementImpl) { - final RefineEffectiveStatementImpl refineStmt = (RefineEffectiveStatementImpl) effectiveStatement; - refinesInit.put(refineStmt.argument(), refineStmt.getRefineTargetNode()); - } - } - this.augmentations = ImmutableSet.copyOf(augmentationsInit); - this.refines = ImmutableMap.copyOf(refinesInit); - - whenCondition = findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class).orElse(null); - } - - @Override - public GroupingDefinition getSourceGrouping() { - return sourceGrouping; - } - - @Override - public Collection getAugmentations() { - return augmentations; - } - - @Deprecated - @Override - public boolean isAugmenting() { - return false; - } - - @Deprecated - @Override - public boolean isAddedByUses() { - return addedByUses; - } - - @Override - public Map getRefines() { - return refines; - } - - @Override - public Optional getWhenCondition() { - return Optional.ofNullable(whenCondition); - } - - @Override - public String toString() { - return UsesEffectiveStatementImpl.class.getSimpleName() + "[sourceGrouping=" + sourceGrouping.getQName() + "]"; - } -} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementSupport.java index 25df180192..3fffa8a010 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementSupport.java @@ -8,24 +8,39 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.uses; import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Optional; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.YangVersion; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; +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.meta.StatementDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.RefineEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace; import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.YangValidationBundles; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseQNameStatementSupport; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.refine.RefineEffectiveStatementImpl; import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; @@ -46,7 +61,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class UsesStatementSupport - extends AbstractQNameStatementSupport { + extends BaseQNameStatementSupport { private static final Logger LOG = LoggerFactory.getLogger(UsesStatementSupport.class); private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping .USES) @@ -112,18 +127,73 @@ public final class UsesStatementSupport } @Override - public UsesStatement createDeclared(final StmtContext ctx) { - return new UsesStatementImpl(ctx); + protected SubstatementValidator getSubstatementValidator() { + return SUBSTATEMENT_VALIDATOR; } @Override - public UsesEffectiveStatement createEffective(final StmtContext ctx) { - return new UsesEffectiveStatementImpl(ctx); + protected UsesStatement createDeclared(final StmtContext ctx, + final ImmutableList> substatements) { + return new RegularUsesStatement(ctx, substatements); } @Override - protected SubstatementValidator getSubstatementValidator() { - return SUBSTATEMENT_VALIDATOR; + protected UsesStatement createEmptyDeclared(final StmtContext ctx) { + return new EmptyUsesStatement(ctx); + } + + @Override + protected UsesEffectiveStatement createEffective( + final StmtContext ctx, final UsesStatement declared, + final ImmutableList> substatements) { + final GroupingDefinition sourceGrouping = getSourceGrouping(ctx); + final int flags = computeFlags(ctx, substatements); + final QName argument = ctx.coerceStatementArgument(); + if (declared.argument().equals(argument)) { + return new RegularLocalUsesEffectiveStatement(declared, sourceGrouping, flags, substatements); + } + if (findFirstStatement(substatements, RefineEffectiveStatement.class) == null) { + return new SimpleCopiedUsesEffectiveStatement(declared, argument, sourceGrouping, flags, substatements); + } + return new FullCopiedUsesEffectiveStatement(declared, argument, sourceGrouping, flags, substatements); + } + + @Override + protected UsesEffectiveStatement createEmptyEffective( + final StmtContext ctx, final UsesStatement declared) { + final GroupingDefinition sourceGrouping = getSourceGrouping(ctx); + final int flags = computeFlags(ctx, ImmutableList.of()); + final QName argument = ctx.coerceStatementArgument(); + return argument.equals(declared.argument()) + ? new EmptyLocalUsesEffectiveStatement(declared, sourceGrouping, flags) + : new SimpleCopiedUsesEffectiveStatement(declared, argument, sourceGrouping, flags); + } + + static @NonNull ImmutableMap indexRefines( + final ImmutableList> substatements) { + final Map refines = new LinkedHashMap<>(); + + for (EffectiveStatement effectiveStatement : substatements) { + if (effectiveStatement instanceof RefineEffectiveStatementImpl) { + final RefineEffectiveStatementImpl refineStmt = (RefineEffectiveStatementImpl) effectiveStatement; + refines.put(refineStmt.argument(), refineStmt.getRefineTargetNode()); + } + } + + return ImmutableMap.copyOf(refines); + } + + private static GroupingDefinition getSourceGrouping(final StmtContext ctx) { + return (GroupingDefinition) ctx.getFromNamespace(GroupingNamespace.class, ctx.coerceStatementArgument()) + .buildEffective(); + } + + private static int computeFlags(final StmtContext ctx, + final ImmutableList> substatements) { + return new FlagsBuilder() + .setHistory(ctx.getCopyHistory()) + .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT)) + .toFlags(); } /** -- 2.36.6