import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.OnDemandSchemaTreeStorageNode;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextDefaults;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return hasEmptyEffectiveSubstatements();
}
+ @Override
+ public <X, Z extends EffectiveStatement<X, ?>> @NonNull Optional<X> findSubstatementArgument(
+ final @NonNull Class<Z> type) {
+ if (substatementsInitialized()) {
+ return StmtContextDefaults.findSubstatementArgument(this, type);
+ }
+
+ final Optional<X> templateArg = prototype.findSubstatementArgument(type);
+ if (templateArg.isEmpty()) {
+ return templateArg;
+ }
+ if (SchemaTreeEffectiveStatement.class.isAssignableFrom(type)) {
+ // X is known to be QName
+ return (Optional<X>) templateArg.map(template -> ((QName) template).bindTo(targetModule));
+ }
+ return templateArg;
+ }
+
+ @Override
+ public boolean hasSubstatement(final @NonNull Class<? extends EffectiveStatement<?, ?>> type) {
+ return substatementsInitialized() ? StmtContextDefaults.hasSubstatement(prototype, type)
+ : prototype.hasSubstatement(type);
+ }
+
@Override
public <D extends DeclaredStatement<QName>, E extends EffectiveStatement<QName, D>>
StmtContext<QName, D, E> requestSchemaTreeChild(final QName qname) {
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.WhenEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.ArgumentUtils;
}
private static boolean hasWhenSubstatement(final StmtContext<?, ?, ?> ctx) {
- return StmtContextUtils.findFirstSubstatement(ctx, WhenStatement.class) != null;
+ return ctx.hasSubstatement(WhenEffectiveStatement.class);
}
private static void copyStatement(final Mutable<?, ?, ?> original, final StatementContextBase<?, ?, ?> target,
void setIsSupportedToBuildEffective(boolean isSupportedToBuild);
}
+
+ /**
+ * Search of any child statement context of specified type and return its argument. If such a statement exists, it
+ * is assumed to have the right argument. Users should be careful to use this method for statements which have
+ * cardinality {@code 0..1}, otherwise this method can return any one of the statement's argument.
+ *
+ * <p>
+ * The default implementation defers to
+ * {@link StmtContextDefaults#findSubstatementArgument(StmtContext, Class)}, subclasses are expected to provide
+ * optimized implementation if possible.
+ *
+ * @param <X> Substatement argument type
+ * @param <Z> Substatement effective statement representation
+ * @param type Effective statement representation being look up
+ * @return {@link Optional#empty()} if no statement exists, otherwise the argument value
+ */
+ default <X, Z extends EffectiveStatement<X, ?>> @NonNull Optional<X> findSubstatementArgument(
+ final @NonNull Class<Z> type) {
+ return StmtContextDefaults.findSubstatementArgument(this, type);
+ }
+
+ /**
+ * Check if there is any child statement context of specified type.
+ *
+ * <p>
+ * The default implementation defers to {@link StmtContextDefaults#hasSubstatement(StmtContext, Class)},
+ * subclasses are expected to provide optimized implementation if possible.
+ *
+ * @param type Effective statement representation being look up
+ * @return True if such a child statement exists, false otherwise
+ */
+ default boolean hasSubstatement(final @NonNull Class<? extends EffectiveStatement<?, ?>> type) {
+ return StmtContextDefaults.hasSubstatement(this, type);
+ }
}
--- /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.spi.meta;
+
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Default implementations for various {@link StmtContext} methods. Code hosted here is meant for use by actual
+ * {@link StmtContext} implementations, not for general use by others.
+ */
+public final class StmtContextDefaults {
+ private StmtContextDefaults() {
+ // Hidden on purpose
+ }
+
+ /**
+ * Default implementation of {@link StmtContext#findSubstatementArgument(Class)}. See that method for API contract.
+ *
+ * @param <A> Substatement argument type
+ * @param <E> Substatement effective statement representation
+ * @param stmt Statement context to search
+ * @param type Effective statement representation being look up
+ * @return Effective statement argument, if found
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static <A, E extends EffectiveStatement<A, ?>> @NonNull Optional<A> findSubstatementArgument(
+ final @NonNull StmtContext<?, ?, ?> stmt, final @NonNull Class<E> type) {
+ return stmt.allSubstatementsStream()
+ .filter(ctx -> ((StmtContext) ctx).producesEffective(type))
+ .findAny()
+ .map(ctx -> (A) ctx.coerceStatementArgument());
+ }
+
+ /**
+ * Default implementation of {@link StmtContext#hasSubstatement(Class)}. See that method for API contract.
+ *
+ * @param stmt Statement context to search
+ * @param type Effective statement representation being look up
+ * @return True if a match is found, false otherwise
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static boolean hasSubstatement(final @NonNull StmtContext<?, ?, ?> stmt,
+ @SuppressWarnings("rawtypes") final @NonNull Class<? extends EffectiveStatement<?, ?>> type) {
+ return stmt.allSubstatementsStream().anyMatch(ctx -> ((StmtContext) ctx).producesEffective(type));
+ }
+}
import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
* @param <A> statement argument type
* @param <D> declared statement type
* @return statement context that was searched for or null if was not found
+ * @deprecated Use {@link StmtContext#findSubstatementArgument(Class)} instead.
*/
+ @Deprecated(forRemoval = true)
public static <A, D extends DeclaredStatement<A>> StmtContext<A, ?, ?> findFirstSubstatement(
final StmtContext<?, ?, ?> stmtContext, final Class<D> declaredType) {
final StmtContext<A, ?, ?> effectiveSubstatement = findFirstEffectiveSubstatement(stmtContext, declaredType);
}
private static boolean containsPresenceSubStmt(final StmtContext<?, ?, ?> stmtCtx) {
- return findFirstSubstatement(stmtCtx, PresenceStatement.class) != null;
+ return stmtCtx.hasSubstatement(PresenceEffectiveStatement.class);
}
/**
StmtContext<?, ?, ?> current = ctx.coerceParentContext();
StmtContext<?, ?, ?> parent = current.getParentContext();
while (parent != null) {
- if (ancestorType.equals(current.getPublicDefinition())) {
- @SuppressWarnings("unchecked")
- final Class<D> ancestorChildTypeClass = (Class<D>) ancestorChildType.getDeclaredRepresentationClass();
- if (findFirstSubstatement(current, ancestorChildTypeClass) == null) {
- return false;
- }
+ if (ancestorType.equals(current.getPublicDefinition())
+ && !current.hasSubstatement(ancestorChildType.getEffectiveRepresentationClass())) {
+ return false;
}
current = parent;