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 GroupingEffectiveStatement extends EffectiveStatement<QName, GroupingStatement> {
-
+ @Override
+ default StatementDefinition statementDefinition() {
+ return YangStmtMapping.GROUPING;
+ }
}
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
public interface GroupingStatement extends DocumentedDeclaredStatement.WithStatus<QName>,
DataDefinitionAwareDeclaredStatement.WithReusableDefinitions<QName>,
NotificationStatementAwareDeclaredStatement<QName>, ActionStatementAwareDeclaredStatement<QName> {
+ @Override
+ default StatementDefinition statementDefinition() {
+ return YangStmtMapping.GROUPING;
+ }
+
default @NonNull QName getName() {
// FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
return verifyNotNull(argument());
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DataNodeContainerMixin;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
/**
}
}
+ /**
+ * Utility class for implementing DataNodeContainer-type statements.
+ */
+ public abstract static class DefaultDataNodeContainer<A, D extends DeclaredStatement<A>> extends Default<A, D>
+ implements DataNodeContainerMixin<A, D> {
+ private final @NonNull ImmutableMap<QName, DataSchemaNode> dataChildren;
+ private final @NonNull Object substatements;
+
+ protected DefaultDataNodeContainer(final D declared, final StatementSourceReference ref,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ super(declared);
+ this.substatements = maskList(substatements);
+
+ // Note: we do not leak this map, so iteration order does not matter
+ final Map<QName, DataSchemaNode> tmp = new HashMap<>();
+
+ for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
+ if (stmt instanceof DataSchemaNode) {
+ final DataSchemaNode node = (DataSchemaNode) stmt;
+ final QName id = node.getQName();
+ final DataSchemaNode prev = tmp.put(id, node);
+ SourceException.throwIf(prev != null, ref,
+ "Cannot add child with name %s, a conflicting child already exists", id);
+ }
+ }
+
+ dataChildren = ImmutableMap.copyOf(tmp);
+ }
+
+ @Override
+ public final ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+ return unmaskList(substatements);
+ }
+
+ @Override
+ public final Optional<DataSchemaNode> findDataChildByName(final QName name) {
+ return Optional.ofNullable(dataChildren.get(requireNonNull(name)));
+ }
+ }
+
/**
* An extra building block on top of {@link Default}, which is wiring {@link #argument()} to the declared statement.
* This is mostly useful for arguments that are not subject to inference transformation -- for example Strings in
*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.grouping;
+import com.google.common.collect.ImmutableList;
import org.opendaylight.yangtools.yang.common.QName;
+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.stmt.GroupingEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
+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.spi.GroupingNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
abstract class AbstractGroupingStatementSupport
- extends AbstractQNameStatementSupport<GroupingStatement, GroupingEffectiveStatement> {
-
+ extends BaseQNameStatementSupport<GroupingStatement, GroupingEffectiveStatement> {
AbstractGroupingStatementSupport() {
super(YangStmtMapping.GROUPING);
}
return StmtContextUtils.parseIdentifier(ctx, value);
}
- @Override
- public final GroupingStatement createDeclared(final StmtContext<QName, GroupingStatement, ?> ctx) {
- // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure
- // that a grouping in child scope does not shadow a grouping in parent scope which occurs later in the text.
- final StmtContext<?, ?, ?> parent = ctx.getParentContext();
- if (parent != null) {
- final StmtContext<?, ?, ?> grandParent = parent.getParentContext();
- if (grandParent != null) {
- checkConflict(grandParent, ctx);
- }
- }
-
- return new GroupingStatementImpl(ctx);
- }
-
- @Override
- public final GroupingEffectiveStatement createEffective(
- final StmtContext<QName, GroupingStatement, GroupingEffectiveStatement> ctx) {
- return new GroupingEffectiveStatementImpl(ctx);
- }
-
@Override
public final void onFullDefinitionDeclared(
final Mutable<QName, GroupingStatement, GroupingEffectiveStatement> stmt) {
}
}
+ @Override
+ protected final GroupingStatement createDeclared(final StmtContext<QName, GroupingStatement, ?> ctx,
+ final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+ checkDeclaredConflict(ctx);
+ return new RegularGroupingStatement(ctx.coerceStatementArgument(), substatements);
+ }
+
+ @Override
+ protected final GroupingStatement createEmptyDeclared(final StmtContext<QName, GroupingStatement, ?> ctx) {
+ checkDeclaredConflict(ctx);
+ return new EmptyGroupingStatement(ctx.coerceStatementArgument());
+ }
+
+ @Override
+ protected final GroupingEffectiveStatement createEffective(
+ final StmtContext<QName, GroupingStatement, GroupingEffectiveStatement> ctx,
+ final GroupingStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ final int flags = new FlagsBuilder()
+ .setHistory(ctx.getCopyHistory())
+ .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))
+ .toFlags();
+
+ return new GroupingEffectiveStatementImpl(declared, ctx.getSchemaPath().get(), flags, substatements,
+ ctx.getStatementSourceReference());
+ }
+
+ @Override
+ protected GroupingEffectiveStatement createEmptyEffective(
+ final StmtContext<QName, GroupingStatement, GroupingEffectiveStatement> ctx,
+ final GroupingStatement declared) {
+ return createEffective(ctx, declared, ImmutableList.of());
+ }
+
+ private static void checkDeclaredConflict(final StmtContext<QName, ?, ?> ctx) {
+ // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure
+ // that a grouping in child scope does not shadow a grouping in parent scope which occurs later in the text.
+ final StmtContext<?, ?, ?> parent = ctx.getParentContext();
+ if (parent != null) {
+ final StmtContext<?, ?, ?> grandParent = parent.getParentContext();
+ if (grandParent != null) {
+ checkConflict(grandParent, ctx);
+ }
+ }
+ }
+
private static void checkConflict(final StmtContext<?, ?, ?> parent, final StmtContext<QName, ?, ?> stmt) {
final QName arg = stmt.coerceStatementArgument();
final StmtContext<?, ?, ?> existing = parent.getFromNamespace(GroupingNamespace.class, arg);
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument;
-public class GroupingStatementImpl extends AbstractDeclaredStatement<QName>
- implements GroupingStatement {
- GroupingStatementImpl(final StmtContext<QName, GroupingStatement, ?> context) {
- super(context);
+final class EmptyGroupingStatement extends WithQNameArgument implements GroupingStatement {
+ EmptyGroupingStatement(final QName argument) {
+ super(argument);
}
}
*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.grouping;
-import com.google.common.collect.ImmutableSet;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
import java.util.Objects;
-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.ActionDefinition;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
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.compat.ActionNodeContainerCompat;
import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveDocumentedDataNodeContainer;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultDataNodeContainer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.ActionNodeContainerMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.AddedByUsesMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.NotificationNodeContainerMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.SchemaNodeMixin;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
final class GroupingEffectiveStatementImpl
- extends AbstractEffectiveDocumentedDataNodeContainer<QName, GroupingStatement>
+ extends DefaultDataNodeContainer<QName, GroupingStatement>
implements GroupingDefinition, GroupingEffectiveStatement,
+ SchemaNodeMixin<QName, GroupingStatement>, ActionNodeContainerMixin<QName, GroupingStatement>,
ActionNodeContainerCompat<QName, GroupingStatement>,
- NotificationNodeContainerCompat<QName, GroupingStatement> {
- private final @NonNull QName qname;
+ NotificationNodeContainerCompat<QName, GroupingStatement>,
+ NotificationNodeContainerMixin<QName, GroupingStatement>, AddedByUsesMixin<QName, GroupingStatement> {
private final @NonNull SchemaPath path;
- private final boolean addedByUses;
- private final @NonNull ImmutableSet<ActionDefinition> actions;
- private final @NonNull ImmutableSet<NotificationDefinition> notifications;
-
- GroupingEffectiveStatementImpl(final StmtContext<QName, GroupingStatement, GroupingEffectiveStatement> ctx) {
- super(ctx);
-
- qname = ctx.coerceStatementArgument();
- path = ctx.getSchemaPath().get();
- addedByUses = ctx.getCopyHistory().contains(CopyType.ADDED_BY_USES);
-
- final ImmutableSet.Builder<ActionDefinition> actionsBuilder = ImmutableSet.builder();
- final ImmutableSet.Builder<NotificationDefinition> notificationsBuilder = ImmutableSet.builder();
- for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
- if (effectiveStatement instanceof ActionDefinition) {
- actionsBuilder.add((ActionDefinition) effectiveStatement);
- }
- if (effectiveStatement instanceof NotificationDefinition) {
- notificationsBuilder.add((NotificationDefinition) effectiveStatement);
- }
- }
+ private final int flags;
- this.actions = actionsBuilder.build();
- this.notifications = notificationsBuilder.build();
+ GroupingEffectiveStatementImpl(final GroupingStatement declared, final SchemaPath path, final int flags,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final StatementSourceReference ref) {
+ super(declared, ref, substatements);
+ this.path = requireNonNull(path);
+ this.flags = flags;
}
@Override
- public QName getQName() {
- return qname;
+ public int flags() {
+ return flags;
}
@Override
- public SchemaPath getPath() {
- return path;
+ public @Nullable QName argument() {
+ return getQName();
}
@Override
- public boolean isAddedByUses() {
- return addedByUses;
- }
-
- @Override
- public Set<ActionDefinition> getActions() {
- return actions;
- }
-
- @Override
- public Set<NotificationDefinition> getNotifications() {
- return notifications;
+ public SchemaPath getPath() {
+ return path;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + Objects.hashCode(qname);
+ result = prime * result + Objects.hashCode(getQName());
result = prime * result + Objects.hashCode(path);
return result;
}
if (this == obj) {
return true;
}
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
+ if (obj == null || getClass() != obj.getClass()) {
return false;
}
final GroupingEffectiveStatementImpl other = (GroupingEffectiveStatementImpl) obj;
- return Objects.equals(qname, other.qname) && Objects.equals(path, other.path);
+ return Objects.equals(getQName(), other.getQName()) && Objects.equals(path, other.path);
}
@Override
public String toString() {
- return GroupingEffectiveStatementImpl.class.getSimpleName() + "[" + "qname=" + qname + "]";
+ return GroupingEffectiveStatementImpl.class.getSimpleName() + "[" + "qname=" + getQName() + "]";
}
}
--- /dev/null
+/*
+ * 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.grouping;
+
+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.GroupingStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
+
+final class RegularGroupingStatement extends WithSubstatements implements GroupingStatement {
+ RegularGroupingStatement(final QName argument, final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+ super(argument, substatements);
+ }
+}