The following kind of loop in the typedefs causes stack overflow error during the compilation of the yang file:
typedef foo {
type bar;
}
typedef bar {
type foo;
}
The compiler should provide descriptive error message instead.
Change-Id: Ia752a7de4a6e1ec1c7018fadc1428845d820e390
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
import java.util.Collection;
import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
+import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ExtendedTypeEffectiveStatementImpl;
return new ExtendedTypeEffectiveStatementImpl(ctx, false);
}
}
+
+ @Override
+ public void onFullDefinitionDeclared(
+ final Mutable<String, TypeStatement, EffectiveStatement<String, TypeStatement>> stmt)
+ throws SourceException {
+
+ // if it is yang built-in type, no prerequisite is needed, so simply return
+ if (TypeUtils.isYangBuiltInTypeString(stmt.getStatementArgument())) {
+ return;
+ }
+
+ final QName typeQName = Utils.qNameFromArgument(stmt, stmt.getStatementArgument());
+ 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.
+ */
+ typeAction.apply(new InferenceAction() {
+
+ @Override
+ public void apply() {
+ // Intentional NOOP
+ }
+
+ @Override
+ public void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) {
+ if (failed.contains(typePrereq)) {
+ throw new InferenceException(String.format("Type [%s] was not found.", typeQName), stmt
+ .getStatementSourceReference());
+ }
+ }
+ });
+ }
}
@Nonnull
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+
+import com.google.common.base.Throwables;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.util.YangParseException;
import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
-import com.google.common.base.Throwables;
public class YangParserNegativeTest {
try {
try (InputStream stream = new FileInputStream(yang)) {
TestUtils.loadModule(stream);
- fail("IllegalArgumentException should be thrown");
+ fail("SomeModifiersUnresolvedException should be thrown.");
}
- } catch (IllegalStateException e) {
- assertTrue(e.getMessage().startsWith(
- "Type '(urn:simple.types.data.demo?revision=2013-02-27)int-ext' was not found"));
+ } catch (SomeModifiersUnresolvedException e) {
+ Throwable rootCause = Throwables.getRootCause(e);
+ assertTrue(rootCause instanceof InferenceException);
+ assertTrue(rootCause.getMessage()
+ .startsWith("Type [(urn:simple.types.data.demo?revision=2013-02-27)int-ext] was not found."));
}
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. 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.stmt.test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Throwables;
+import java.io.FileNotFoundException;
+import java.net.URISyntaxException;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+public class Bug4410Test {
+
+ @Test
+ public void test() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException {
+ try {
+ StmtTestUtils.parseYangSources("/bugs/bug4410");
+ fail("SomeModifiersUnresolvedException should be thrown.");
+ } catch (SomeModifiersUnresolvedException e) {
+ Throwable rootCause = Throwables.getRootCause(e);
+ assertTrue(rootCause instanceof InferenceException);
+ final String message = rootCause.getMessage();
+ assertTrue(message.startsWith("Type [(foo?revision=1970-01-01)"));
+ assertTrue(message.endsWith("was not found."));
+ }
+ }
+}
--- /dev/null
+module foo {
+ namespace "foo";
+ prefix "foo";
+ yang-version 1;
+
+ typedef foo {
+ type bar;
+ }
+
+ typedef bar {
+ type foo;
+ }
+}