Defer copy decisions to StatementSupport
[yangtools.git] / yang / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / StatementSupport.java
index 8465e3881eb6badef2a0657a31b1232b5237e2da..fb30a4a61204ddd455109565531a639e968b327b 100644 (file)
@@ -5,37 +5,34 @@
  * 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 com.google.common.annotations.Beta;
 import java.util.Optional;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.meta.ArgumentDefinition;
 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.parser.spi.meta.StmtContext.Mutable;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 /**
  * Support for processing concrete YANG statement.
  *
  * <p>
- * This interface is intended to be implemented by developers, which want to
- * introduce support of statement to parser. Consider subclassing
- * {@link AbstractStatementSupport} for easier implementation of this interface.
+ * This interface is intended to be implemented by developers, which want to introduce support of statement to parser.
+ * Consider subclassing {@link AbstractStatementSupport} for easier implementation of this interface.
  *
- * @param <A>
- *            Argument type
- * @param <D>
- *            Declared Statement representation
- * @param <E>
- *            Effective Statement representation
+ * @param <A> Argument type
+ * @param <D> Declared Statement representation
+ * @param <E> Effective Statement representation
  */
-// FIXME: 3.0.0: do not extends ImplicitParentAwareStatementSupport
 public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
-        extends StatementDefinition, StatementFactory<A, D, E>, ImplicitParentAwareStatementSupport {
-
+        extends StatementDefinition, StatementFactory<A, D, E> {
     /**
      * Returns public statement definition, which will be present in built statements.
      *
@@ -43,33 +40,25 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * Public statement definition may be used to provide different implementation of statement definition,
      * which will not retain any build specific data or context.
      *
-     * @return public statement definition, which will be present in built
-     *         statements.
+     * @return public statement definition, which will be present in built statements.
      */
-    StatementDefinition getPublicView();
+    @NonNull StatementDefinition getPublicView();
 
     /**
      * Parses textual representation of argument in object representation.
      *
-     * @param ctx
-     *            Context, which may be used to access source-specific
-     *            namespaces required for parsing.
-     * @param value
-     *            String representation of value, as was present in text source.
+     * @param ctx Context, which may be used to access source-specific namespaces required for parsing.
+     * @param value String representation of value, as was present in text source.
      * @return Parsed value
-     * @throws SourceException
-     *             when an inconsistency is detected.
+     * @throws SourceException when an inconsistency is detected.
      */
     A parseArgumentValue(StmtContext<?, ?, ?> ctx, String value);
 
     /**
      * Adapts the argument value to match a new module.
      *
-     * @param ctx
-     *            Context, which may be used to access source-specific
-     *            namespaces required for parsing.
-     * @param targetModule
-     *            Target module, may not be null.
+     * @param ctx Context, which may be used to access source-specific namespaces required for parsing.
+     * @param targetModule Target module, may not be null.
      * @return Adapted argument value. The default implementation returns original value stored in context.
      */
     default A adaptArgumentValue(final StmtContext<A, D, E> ctx, final QNameModule targetModule) {
@@ -82,17 +71,10 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * accessible via {@link StmtContext#getParentContext()}. One such use is populating the parent's namespaces to
      * allow it to locate this child statement.
      *
-     * @param stmt
-     *            Context of added statement. No substatements are available.
+     * @param stmt Context of added statement. No substatements are available.
      */
     void onStatementAdded(StmtContext.Mutable<A, D, E> stmt);
 
-    // FIXME: 3.0.0: remove this default method
-    @Override
-    default Optional<StatementSupport<?, ?, ?>> getImplicitParentFor(final StatementDefinition stmtDef) {
-        return Optional.empty();
-    }
-
     /**
      * Invoked when statement is closed during {@link ModelProcessingPhase#SOURCE_PRE_LINKAGE} phase, only substatements
      * from this and previous phase are available.
@@ -101,8 +83,7 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * Implementation may use method to perform actions on this event or register modification action using
      * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
      *
-     * @param stmt
-     *            Context of added statement.
+     * @param stmt Context of added statement.
      */
     void onPreLinkageDeclared(StmtContext.Mutable<A, D, E> stmt);
 
@@ -114,10 +95,8 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * Implementation may use method to perform actions on this event or register modification action using
      * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
      *
-     * @param stmt
-     *            Context of added statement.
-     * @throws SourceException
-     *             when an inconsistency is detected.
+     * @param stmt Context of added statement.
+     * @throws SourceException when an inconsistency is detected.
      */
     void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt);
 
@@ -129,11 +108,8 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * Implementation may use method to perform actions on this event or register modification action using
      * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
      *
-     * @param stmt
-     *            Context of added statement. Argument and statement parent is
-     *            accessible.
-     * @throws SourceException
-     *             when an inconsistency is detected.
+     * @param stmt Context of added statement. Argument and statement parent is accessible.
+     * @throws SourceException when an inconsistency is detected.
      */
     void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt);
 
@@ -145,11 +121,8 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * Implementation may use method to perform actions on this event or register modification action using
      * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
      *
-     * @param stmt
-     *            Context of added statement. Argument and statement parent is
-     *            accessible.
-     * @throws SourceException
-     *             when an inconsistency is detected.
+     * @param stmt Context of added statement. Argument and statement parent is accessible.
+     * @throws SourceException when an inconsistency is detected.
      */
     void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt);
 
@@ -162,18 +135,34 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * If this support has argument specific supports, the method returns support specific for given argument
      * (e.g. type statement support need to be specialized based on its argument), otherwise returns null.
      *
-     * @param argument
-     *            argument of statement
+     * @param argument argument of statement
      * @return statement support specific for supplied argument or null
      */
-    @Nullable
-    StatementSupport<?, ?, ?> getSupportSpecificForArgument(String argument);
+    @Nullable StatementSupport<?, ?, ?> getSupportSpecificForArgument(String argument);
+
+    /**
+     * Create an optional copy of specified statement as a substatement of parent.
+     *
+     * <p>
+     * Note that while it may be tempting to return the same context, this is not safe in general case. It is only safe
+     * if the entire subtree is unaffected by changes to parent/namespace/history. This includes the semantics of this
+     * statement (it cannot be a target of any inference effects) as well as any substatements -- an extension statement
+     * is allowed pretty much anywhere and if its semantics are context-dependent, a simple instance reuse will not
+     * work.
+     *
+     * @param stmt Context of statement to be copied statement.
+     * @param parent Parent statement context
+     * @param type Type of copy being performed
+     * @param targetModule Target module, if present
+     * @return Empty if the statement should be ignored, or present with an instance that should be copied into parent.
+     */
+    @NonNull Optional<? extends Mutable<?, ?, ?>> copyAsChildOf(Mutable<?, ?, ?> stmt, Mutable<?, ?, ?> parent,
+            CopyType type, @Nullable QNameModule targetModule);
 
     /**
      * Given a raw string representation of an argument, try to use a shared representation.
      *
-     * @param rawArgument
-     *            Argument string
+     * @param rawArgument Argument string
      * @return A potentially-shard instance
      */
     default String internArgument(final String rawArgument) {
@@ -183,10 +172,9 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
     /**
      * Returns unknown statement form of a regular YANG statement supplied as a parameter to the method.
      *
-     * @param yangStmtDef
-     *            statement definition of a regular yang statement
-     * @return Optional of unknown statement form of a regular yang statement or
-     *         Optional.empty() if it is not supported by this statement support
+     * @param yangStmtDef statement definition of a regular YANG statement
+     * @return Optional of unknown statement form of a regular YANG statement or empty() if it is not supported by this
+     *         statement support
      */
     default Optional<StatementSupport<?, ?, ?>> getUnknownStatementDefinitionOf(final StatementDefinition yangStmtDef) {
         return Optional.empty();
@@ -217,4 +205,24 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
     default boolean isIgnoringConfig() {
         return false;
     }
+
+    @Override
+    default QName getStatementName() {
+        return getPublicView().getStatementName();
+    }
+
+    @Override
+    default @NonNull Optional<ArgumentDefinition> getArgumentDefinition() {
+        return getPublicView().getArgumentDefinition();
+    }
+
+    @Override
+    default Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+        return getPublicView().getDeclaredRepresentationClass();
+    }
+
+    @Override
+    default Class<? extends EffectiveStatement<?,?>> getEffectiveRepresentationClass() {
+        return getPublicView().getEffectiveRepresentationClass();
+    }
 }