import static com.google.common.base.Verify.verify;
+import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.KeyEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementLexer;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
public final class KeyStatementSupport
extends BaseStatementSupport<Set<QName>, KeyStatement, KeyEffectiveStatement> {
- private static final Splitter LIST_KEY_SPLITTER = Splitter.on(' ').omitEmptyStrings().trimResults();
+ /**
+ * This is equivalent to {@link YangStatementLexer#SEP}'s definition. Currently equivalent to the non-repeating
+ * part of:
+ *
+ * <p>
+ * {@code SEP: [ \n\r\t]+ -> type(SEP);}.
+ */
+ private static final CharMatcher SEP = CharMatcher.anyOf(" \n\r\t").precomputed();
+
+ /**
+ * Splitter corresponding to {@code key-arg} ABNF as defined
+ * in <a href="https://tools.ietf.org/html/rfc6020#section-12">RFC6020, section 12</a>:
+ *
+ * <p>
+ * {@code key-arg = node-identifier *(sep node-identifier)}
+ *
+ * <p>
+ * We also account for {@link #SEP} not handling repetition by ignoring empty strings.
+ */
+ private static final Splitter KEY_ARG_SPLITTER = Splitter.on(SEP).omitEmptyStrings();
+
private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(
YangStmtMapping.KEY)
.build();
public ImmutableSet<QName> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
final Builder<QName> builder = ImmutableSet.builder();
int tokens = 0;
- for (String keyToken : LIST_KEY_SPLITTER.split(value)) {
+ for (String keyToken : KEY_ARG_SPLITTER.split(value)) {
builder.add(StmtContextUtils.parseNodeIdentifier(ctx, keyToken));
tokens++;
}
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+public class YT1200Test {
+ private static final QName FOO = QName.create("urn:foo", "foo");
+
+ @Test
+ public void testKeyParsing() throws Exception {
+ final DataSchemaNode foo = StmtTestUtils.parseYangSource("/bugs/YT1200/foo.yang").getDataChildByName(FOO);
+ assertThat(foo, instanceOf(ListSchemaNode.class));
+ assertEquals(List.of(FOO, QName.create(FOO, "bar"), QName.create(FOO, "baz")),
+ ((ListSchemaNode) foo).getKeyDefinition());
+ }
+}