Convert trivial CopyPolicy users to StatementPolicy
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / ordered_by / OrderedByStatementSupport.java
index d7244ea5b55a2dbbb633ed44ecb61427d5be14c9..fdacec33e4b630aef9aaf74621c103a079bd2d06 100644 (file)
@@ -8,12 +8,15 @@
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.ordered_by;
 
 import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Ordering;
 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.OrderedByEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement.Ordering;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@@ -24,8 +27,21 @@ public final class OrderedByStatementSupport
             SubstatementValidator.builder(YangStmtMapping.ORDERED_BY).build();
     private static final OrderedByStatementSupport INSTANCE = new OrderedByStatementSupport();
 
+    /*
+     * Ordered-by has low argument cardinality, hence we can reuse them in case declaration does not have any
+     * substatements (which is the usual case).
+     */
+    private static final @NonNull EmptyOrderedByStatement EMPTY_SYSTEM_DECL =
+            new EmptyOrderedByStatement(Ordering.SYSTEM);
+    private static final @NonNull EmptyOrderedByStatement EMPTY_USER_DECL =
+            new EmptyOrderedByStatement(Ordering.USER);
+    private static final @NonNull EmptyOrderedByEffectiveStatement EMPTY_SYSTEM_EFF =
+            new EmptyOrderedByEffectiveStatement(EMPTY_SYSTEM_DECL);
+    private static final @NonNull EmptyOrderedByEffectiveStatement EMPTY_USER_EFF =
+            new EmptyOrderedByEffectiveStatement(EMPTY_USER_DECL);
+
     private OrderedByStatementSupport() {
-        super(YangStmtMapping.ORDERED_BY);
+        super(YangStmtMapping.ORDERED_BY, StatementPolicy.contextIndependent());
     }
 
     public static OrderedByStatementSupport getInstance() {
@@ -35,15 +51,21 @@ public final class OrderedByStatementSupport
     @Override
     public Ordering parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
         try {
-            return Ordering.forArgumentString(value);
+            return Ordering.forArgument(value);
         } catch (IllegalArgumentException e) {
-            throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid ordered-by argument '%s'", value);
+            throw new SourceException(ctx, e, "Invalid ordered-by argument '%s'", value);
         }
     }
 
     @Override
-    public OrderedByStatement createDeclared(final StmtContext<Ordering, OrderedByStatement, ?> ctx) {
-        return new OrderedByStatementImpl(ctx);
+    public String internArgument(final String rawArgument) {
+        if ("user".equals(rawArgument)) {
+            return "user";
+        } else if ("system".equals(rawArgument)) {
+            return "system";
+        } else {
+            return rawArgument;
+        }
     }
 
     @Override
@@ -52,28 +74,41 @@ public final class OrderedByStatementSupport
     }
 
     @Override
-    protected OrderedByEffectiveStatement createEffective(
-            final StmtContext<Ordering, OrderedByStatement, OrderedByEffectiveStatement> ctx,
-            final OrderedByStatement declared,
-            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        return new RegularOrderedByEffectiveStatement(declared, substatements);
+    protected OrderedByStatement createDeclared(final StmtContext<Ordering, OrderedByStatement, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        return new RegularOrderedByStatement(ctx.getArgument(), substatements);
     }
 
     @Override
-    protected OrderedByEffectiveStatement createEmptyEffective(
-            final StmtContext<Ordering, OrderedByStatement, OrderedByEffectiveStatement> ctx,
-            final OrderedByStatement declared) {
-        return new EmptyOrderedByEffectiveStatement(declared);
+    protected OrderedByStatement createEmptyDeclared(final StmtContext<Ordering, OrderedByStatement, ?> ctx) {
+        final Ordering argument = ctx.getArgument();
+        switch (argument) {
+            case SYSTEM:
+                return EMPTY_SYSTEM_DECL;
+            case USER:
+                return EMPTY_USER_DECL;
+            default:
+                throw new IllegalStateException("Unhandled argument " + argument);
+        }
     }
 
     @Override
-    public String internArgument(final String rawArgument) {
-        if ("user".equals(rawArgument)) {
-            return "user";
-        } else if ("system".equals(rawArgument)) {
-            return "system";
+    protected OrderedByEffectiveStatement createEffective(final Current<Ordering, OrderedByStatement> stmt,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        return substatements.isEmpty() ? createEmptyEffective(stmt.declared())
+            : new RegularOrderedByEffectiveStatement(stmt.declared(), substatements);
+    }
+
+    private static @NonNull OrderedByEffectiveStatement createEmptyEffective(final OrderedByStatement declared) {
+        // Aggressively reuse effective instances which are backed by the corresponding empty declared instance, as this
+        // is the case unless there is a weird extension in use.
+        if (EMPTY_USER_DECL.equals(declared)) {
+            // Most likely to be seen (as system is the default)
+            return EMPTY_USER_EFF;
+        } else if (EMPTY_SYSTEM_DECL.equals(declared)) {
+            return EMPTY_SYSTEM_EFF;
         } else {
-            return rawArgument;
+            return new EmptyOrderedByEffectiveStatement(declared);
         }
     }
-}
\ No newline at end of file
+}