X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-spi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fspi%2Fmeta%2FStmtContext.java;h=0d3001fb5681612cd7314e41374255e1085b51b6;hb=c1289a7ebed4c08e19a0e8397fe200b84cc56d3e;hp=939d6f2d2b5c5690f6d3c1a43977ba2525394b1b;hpb=bddc66cd44220ae53adb97ba2bbdc9fbdc3a6f8e;p=yangtools.git diff --git a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java index 939d6f2d2b..0d3001fb56 100644 --- a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java +++ b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java @@ -7,14 +7,18 @@ */ package org.opendaylight.yangtools.yang.parser.spi.meta; +import static com.google.common.base.Verify.verifyNotNull; + +import com.google.common.annotations.Beta; +import com.google.common.base.VerifyException; import com.google.common.collect.Iterables; import com.google.common.collect.Streams; import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.SchemaPath; @@ -26,67 +30,134 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; +/** + * An inference context associated with an instance of a statement. + * + * @param Argument type + * @param Declared Statement representation + * @param Effective Statement representation + */ public interface StmtContext, E extends EffectiveStatement> { + /** + * Returns the origin of the statement. + * + * @return origin of statement + */ + @NonNull StatementSource getStatementSource(); - @Nonnull - StatementSource getStatementSource(); - - @Nonnull - StatementSourceReference getStatementSourceReference(); + /** + * Returns a reference to statement source. + * + * @return reference of statement source + */ + @NonNull StatementSourceReference getStatementSourceReference(); - @Nonnull - StatementDefinition getPublicDefinition(); + /** + * See {@link StatementSupport#getPublicView()}. + */ + @NonNull StatementDefinition getPublicDefinition(); /** * Return the parent statement context, or null if this is the root statement. * * @return context of parent of statement, or null if this is the root statement. */ - @Nullable - StmtContext getParentContext(); + @Nullable StmtContext getParentContext(); + + /** + * Return the parent statement context, forcing a VerifyException if this is the root statement. + * + * @return context of parent of statement + * @throws VerifyException if this statement is the root statement + */ + default @NonNull StmtContext coerceParentContext() { + return verifyNotNull(getParentContext(), "Root context %s does not have a parent", this); + } + + /** + * Return the statement argument in literal format. + * + * @return raw statement argument string, or null if this statement does not have an argument. + */ + @Nullable String rawStatementArgument(); + + /** + * Return the statement argument in literal format. + * + * @return raw statement argument string + * @throws VerifyException if this statement does not have an argument + */ + default @NonNull String coerceRawStatementArgument() { + return verifyNotNull(rawStatementArgument(), "Statement context %s does not have an argument", this); + } + + /** + * Return the statement argument. + * + * @return statement argument, or null if this statement does not have an argument + */ + @Nullable A getStatementArgument(); /** * Return the statement argument in literal format. * * @return raw statement argument string + * @throws VerifyException if this statement does not have an argument */ - @Nullable - String rawStatementArgument(); + default @NonNull A coerceStatementArgument() { + return verifyNotNull(getStatementArgument(), "Statement context %s does not have an argument", this); + } + + default > boolean producesDeclared(final Class type) { + return type.isAssignableFrom(getPublicDefinition().getDeclaredRepresentationClass()); + } - @Nullable - A getStatementArgument(); + default > boolean producesEffective(final Class type) { + return type.isAssignableFrom(getPublicDefinition().getEffectiveRepresentationClass()); + } /** * Return the {@link SchemaPath} of this statement. Not all statements have a SchemaPath, in which case * {@link Optional#empty()} is returned. * * @return Optional SchemaPath + * @deprecated Use of SchemaPath in the context of effective statements is going away. Consider not providing this + * information, if your users can exist without it. */ - @Nonnull Optional getSchemaPath(); + @Deprecated + @NonNull Optional getSchemaPath(); boolean isConfiguration(); boolean isEnabledSemanticVersioning(); - @Nonnull - > V getFromNamespace( - Class type, KT key) throws NamespaceNotAvailableException; + /** + * Return a value associated with specified key within a namespace. + * + * @param type Namespace type + * @param key Key + * @param namespace key type + * @param namespace value type + * @param namespace type + * @param key type + * @return Value, or null if there is no element + * @throws NamespaceNotAvailableException when the namespace is not available. + */ + > @Nullable V getFromNamespace(Class<@NonNull N> type, + T key); - > Map getAllFromNamespace( - Class type); + > Map getAllFromNamespace(Class type); > Map getAllFromCurrentStmtCtxNamespace(Class type); - @Nonnull - StmtContext getRoot(); + @NonNull StmtContext getRoot(); /** * Return declared substatements. These are the statements which are explicitly written in the source model. * * @return Collection of declared substatements */ - @Nonnull - Collection> declaredSubstatements(); + @NonNull Collection> declaredSubstatements(); /** * Return effective substatements. These are the statements which are added as this statement's substatements @@ -94,8 +165,7 @@ public interface StmtContext, E extends Effect * * @return Collection of declared substatements */ - @Nonnull - Collection> effectiveSubstatements(); + @NonNull Collection> effectiveSubstatements(); default Iterable> allSubstatements() { return Iterables.concat(declaredSubstatements(), effectiveSubstatements()); @@ -117,13 +187,44 @@ public interface StmtContext, E extends Effect boolean isSupportedToBuildEffective(); + boolean isSupportedByFeatures(); + Collection> getEffectOfStatement(); + /* + * FIXME: YANGTOOLS-784: the next three methods are closely related to the copy process: + * - getCopyHistory() is a brief summary of what went on + * - getOriginalContext() points to the CopyHistory.ORIGINAL + * - getPreviousCopyCtx() points to the immediate predecessor forming a singly-linked list terminated + * at getOriginalContext() + * + * When implementing YANGTOOLS-784, this needs to be taken into account and properly forwarded through + * intermediate MutableTrees. Also note this closely relates to current namespace context, as taken into + * account when creating the argument. At least parts of this are only needed during buildEffective() + * and hence should become arguments to that method. + */ + + /** + * Return the executive summary of the copy process that has produced this context. + * + * @return A simplified summary of the copy process. + */ CopyHistory getCopyHistory(); - boolean isSupportedByFeatures(); + /** + * Return the statement context of the original definition, if this statement is an instantiated copy. + * + * @return Original definition, if this statement was copied. + */ + Optional> getOriginalCtx(); - Optional> getOriginalCtx(); + /** + * Return the context of the previous copy of this statement -- effectively walking towards the source origin + * of this statement. + * + * @return Context of the previous copy of this statement, if this statement has been copied. + */ + Optional> getPreviousCopyCtx(); ModelProcessingPhase getCompletedPhase(); @@ -132,18 +233,42 @@ public interface StmtContext, E extends Effect * * @return version of root statement context */ - @Nonnull YangVersion getRootVersion(); + @NonNull YangVersion getRootVersion(); + /** + * An mutable view of an inference context associated with an instance of a statement. + * + * @param Argument type + * @param Declared Statement representation + * @param Effective Statement representation + */ interface Mutable, E extends EffectiveStatement> extends StmtContext { @Override Mutable getParentContext(); - > void addToNs(Class type, KT key, - VT value) throws NamespaceNotAvailableException; + @Override + default Mutable coerceParentContext() { + return verifyNotNull(getParentContext(), "Root context %s does not have a parent", this); + } + + /** + * Associate a value with a key within a namespace. + * + * @param type Namespace type + * @param key Key + * @param value value + * @param namespace key type + * @param namespace value type + * @param namespace type + * @param key type + * @param value type + * @throws NamespaceNotAvailableException when the namespace is not available. + */ + > void addToNs(Class<@NonNull N> type, + T key, U value); - @Nonnull @Override Mutable getRoot(); @@ -160,8 +285,7 @@ public interface StmtContext, E extends Effect * from an alien implementation. * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException */ - , Z extends EffectiveStatement> Mutable childCopyOf( - StmtContext stmt, CopyType type, @Nullable QNameModule targetModule); + Mutable childCopyOf(StmtContext stmt, CopyType type, @Nullable QNameModule targetModule); /** * Create a child sub-statement, which is a child of this statement, inheriting all attributes from specified @@ -175,26 +299,38 @@ public interface StmtContext, E extends Effect * from an alien implementation. * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException */ - default , Z extends EffectiveStatement> Mutable childCopyOf( - final StmtContext stmt, final CopyType type) { + default Mutable childCopyOf(final StmtContext stmt, final CopyType type) { return childCopyOf(stmt, type, null); } - @Nonnull - Collection> mutableDeclaredSubstatements(); + @Beta + @NonNull Optional> copyAsChildOf(Mutable parent, CopyType type, + @Nullable QNameModule targetModule); + + @Override + default Collection> declaredSubstatements() { + return mutableDeclaredSubstatements(); + } + + @NonNull Collection> mutableDeclaredSubstatements(); - @Nonnull - Collection> mutableEffectiveSubstatements(); + @Override + default Collection> effectiveSubstatements() { + return mutableEffectiveSubstatements(); + } + + @NonNull Collection> mutableEffectiveSubstatements(); /** * Create a new inference action to be executed during specified phase. The action cannot be cancelled - * and will be executed even if its definition remains incomplete. + * and will be executed even if its definition remains incomplete. The specified phase cannot complete until + * this action is resolved. If the action cannot be resolved, model processing will fail. * * @param phase Target phase in which the action will resolved. * @return A new action builder. * @throws NullPointerException if the specified phase is null */ - @Nonnull ModelActionBuilder newInferenceAction(@Nonnull ModelProcessingPhase phase); + @NonNull ModelActionBuilder newInferenceAction(@NonNull ModelProcessingPhase phase); /** * Adds s statement to namespace map with a key. @@ -206,7 +342,7 @@ public interface StmtContext, E extends Effect * @param stmt * to be added to namespace map */ - > void addContext(Class namespace, KT key, + > void addContext(Class<@NonNull N> namespace, KT key, StmtContext stmt); /** @@ -253,8 +389,39 @@ public interface StmtContext, E extends Effect void setRootIdentifier(SourceIdentifier identifier); void setIsSupportedToBuildEffective(boolean isSupportedToBuild); + } - // FIXME: this seems to be unused, but looks useful. - void setCompletedPhase(ModelProcessingPhase completedPhase); + /** + * 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. + * + *

+ * The default implementation defers to + * {@link StmtContextDefaults#findSubstatementArgument(StmtContext, Class)}, subclasses are expected to provide + * optimized implementation if possible. + * + * @param Substatement argument type + * @param 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 > @NonNull Optional findSubstatementArgument( + final @NonNull Class type) { + return StmtContextDefaults.findSubstatementArgument(this, type); + } + + /** + * Check if there is any child statement context of specified type. + * + *

+ * 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> type) { + return StmtContextDefaults.hasSubstatement(this, type); } }