Do not access TypeNamespace during build
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / type / AbstractTypeStatementSupport.java
index d4cfade4b74e139f04497fc032afab6e6e1f480b..2637518739f31c850c7704a52817af207ef626b6 100644 (file)
@@ -14,6 +14,7 @@ import com.google.common.collect.ImmutableMap;
 import java.math.BigDecimal;
 import java.util.Collection;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@@ -30,7 +31,6 @@ import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceEffectiveSt
 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
@@ -168,30 +168,31 @@ abstract class AbstractTypeStatementSupport
         super.onFullDefinitionDeclared(stmt);
 
         // if it is yang built-in type, no prerequisite is needed, so simply return
-        if (BUILT_IN_TYPES.containsKey(stmt.getStatementArgument())) {
+        if (BUILT_IN_TYPES.containsKey(stmt.argument())) {
+            // FIXME: consider populating BaseTypeNamespace here, which could be done quite efficiently, moving the
+            //        logic from resolveType()
             return;
         }
 
-        final QName typeQName = StmtContextUtils.parseNodeIdentifier(stmt, stmt.getStatementArgument());
+        final QName typeQName = StmtContextUtils.parseNodeIdentifier(stmt, stmt.argument());
         final ModelActionBuilder typeAction = stmt.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL);
         final Prerequisite<StmtContext<?, ?, ?>> typePrereq = typeAction.requiresCtx(stmt, TypeNamespace.class,
                 typeQName, ModelProcessingPhase.EFFECTIVE_MODEL);
         typeAction.mutatesEffectiveCtx(stmt.getParentContext());
 
         /*
-         * If the type does not exist, throw new InferenceException.
-         * Otherwise perform no operation.
+         * If the type does not exist, throw an InferenceException.
+         * If the type exists, store a reference to it in BaseTypeNamespace.
          */
         typeAction.apply(new InferenceAction() {
             @Override
             public void apply(final InferenceContext ctx) {
-                // Intentional NOOP
+                stmt.addToNs(BaseTypeNamespace.class, Empty.getInstance(), typePrereq.resolve(ctx));
             }
 
             @Override
             public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) {
-                InferenceException.throwIf(failed.contains(typePrereq), stmt.sourceReference(),
-                    "Type [%s] was not found.", typeQName);
+                InferenceException.throwIf(failed.contains(typePrereq), stmt, "Type [%s] was not found.", typeQName);
             }
         });
     }
@@ -220,14 +221,14 @@ abstract class AbstractTypeStatementSupport
     @Override
     protected final TypeStatement createDeclared(final StmtContext<String, TypeStatement, ?> ctx,
             final ImmutableList<? extends DeclaredStatement<?>> substatements) {
-        return new RegularTypeStatement(ctx.coerceRawStatementArgument(), substatements);
+        return new RegularTypeStatement(ctx.getRawArgument(), substatements);
     }
 
     @Override
     protected final TypeStatement createEmptyDeclared(final StmtContext<String, TypeStatement, ?> ctx) {
         final TypeStatement builtin;
         return (builtin = BuiltinTypeStatement.lookup(ctx)) != null ? builtin
-            : new EmptyTypeStatement(ctx.coerceRawStatementArgument());
+            : new EmptyTypeStatement(ctx.getRawArgument());
     }
 
     @Override
@@ -311,6 +312,11 @@ abstract class AbstractTypeStatementSupport
      * @throws SourceException if the target type cannot be found
      */
     private static @NonNull TypeEffectiveStatement<TypeStatement> resolveType(final Current<String, ?> ctx) {
+        final StmtContext<?, ?, ?> baseType = ctx.namespaceItem(BaseTypeNamespace.class, Empty.getInstance());
+        if (baseType != null) {
+            return ((TypedefEffectiveStatement) baseType.buildEffective()).asTypeEffectiveStatement();
+        }
+
         final String argument = ctx.getArgument();
         switch (argument) {
             case BINARY:
@@ -340,11 +346,7 @@ abstract class AbstractTypeStatementSupport
             case UINT64:
                 return BuiltinEffectiveStatement.UINT64;
             default:
-                final QName qname = StmtContextUtils.parseNodeIdentifier(ctx.caerbannog(), argument);
-                final StmtContext<?, TypedefStatement, TypedefEffectiveStatement> typedef = SourceException.throwIfNull(
-                    ctx.getFromNamespace(TypeNamespace.class, qname), ctx.sourceReference(),
-                    "Type '%s' not found", qname);
-                return typedef.buildEffective().asTypeEffectiveStatement();
+                throw new IllegalStateException("Unhandled type argument " + argument);
         }
     }
 
@@ -361,10 +363,9 @@ abstract class AbstractTypeStatementSupport
                 try {
                     builder.setLengthConstraint(length, length.argument());
                 } catch (IllegalStateException e) {
-                    throw new SourceException(ctx.sourceReference(), e, "Multiple length constraints encountered");
+                    throw new SourceException(ctx, e, "Multiple length constraints encountered");
                 } catch (InvalidLengthConstraintException e) {
-                    throw new SourceException(ctx.sourceReference(), e, "Invalid length constraint %s",
-                        length.argument());
+                    throw new SourceException(ctx, e, "Invalid length constraint %s", length.argument());
                 }
             }
         }
@@ -409,7 +410,7 @@ abstract class AbstractTypeStatementSupport
             }
             if (stmt instanceof FractionDigitsEffectiveStatement) {
                 final Integer digits = ((FractionDigitsEffectiveStatement)stmt).argument();
-                SourceException.throwIf(baseType.getFractionDigits() != digits, ctx.sourceReference(),
+                SourceException.throwIf(baseType.getFractionDigits() != digits, ctx,
                     "Cannot override fraction-digits from base type %s to %s", baseType, digits);
             }
         }
@@ -477,7 +478,7 @@ abstract class AbstractTypeStatementSupport
         try {
             return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
         } catch (InvalidRangeConstraintException e) {
-            throw new SourceException(ctx.sourceReference(), e, "Invalid range constraint: %s", e.getOffendingRanges());
+            throw new SourceException(ctx, e, "Invalid range constraint: %s", e.getOffendingRanges());
         }
     }
 
@@ -508,10 +509,9 @@ abstract class AbstractTypeStatementSupport
                 try {
                     builder.setLengthConstraint(length, length.argument());
                 } catch (IllegalStateException e) {
-                    throw new SourceException(ctx.sourceReference(), e, "Multiple length constraints encountered");
+                    throw new SourceException(ctx, e, "Multiple length constraints encountered");
                 } catch (InvalidLengthConstraintException e) {
-                    throw new SourceException(ctx.sourceReference(), e, "Invalid length constraint %s",
-                        length.argument());
+                    throw new SourceException(ctx, e, "Invalid length constraint %s", length.argument());
                 }
             }
             if (stmt instanceof PatternEffectiveStatement) {