}
@FunctionalInterface
- private interface WriterMethod<T extends PathArgument> {
+ interface WriterMethod<T extends PathArgument> {
void apply(ReusableImmutableNormalizedNodeStreamWriter writer, T name) throws IOException;
}
@FunctionalInterface
- private interface SizedWriterMethod<T extends PathArgument> {
+ interface SizedWriterMethod<T extends PathArgument> {
void apply(ReusableImmutableNormalizedNodeStreamWriter writer, T name, int childSizeHint) throws IOException;
}
public void scalarValue(final Object value) throws IOException {
checkNotSealed();
if (unknown == 0) {
- delegate.scalarValue(translateScalar(stack.peek(), value));
+ delegate.scalarValue(translateScalar(currentSchema(), value));
}
}
}
final DataSchemaContextNode<?> schema;
- final DataSchemaContextNode<?> parent = stack.peek();
+ final DataSchemaContextNode<?> parent = currentSchema();
if (parent != null) {
schema = parent.getChild(name);
} else {
return true;
}
- private <A extends PathArgument> void enter(final WriterMethod<A> method, final A name) throws IOException {
+ final <A extends PathArgument> void enter(final WriterMethod<A> method, final A name) throws IOException {
if (enter(name)) {
method.apply(delegate, name);
}
}
- private <A extends PathArgument> void enter(final SizedWriterMethod<A> method, final A name, final int size)
+ final <A extends PathArgument> void enter(final SizedWriterMethod<A> method, final A name, final int size)
throws IOException {
if (enter(name)) {
method.apply(delegate, name, size);
}
}
+
+ final DataSchemaContextNode<?> currentSchema() {
+ return stack.peek();
+ }
}
package org.opendaylight.controller.cluster.datastore.node.utils.transformer;
import com.google.common.annotations.Beta;
-import java.io.IOException;
-import java.math.BigInteger;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.Uint16;
-import org.opendaylight.yangtools.yang.common.Uint32;
-import org.opendaylight.yangtools.yang.common.Uint64;
-import org.opendaylight.yangtools.yang.common.Uint8;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* The NormalizedNodePruner removes all nodes from the input NormalizedNode that do not have a corresponding
}
}
- private static final class UintAdaptingPruner extends ReusableNormalizedNodePruner {
- private static final Logger LOG = LoggerFactory.getLogger(UintAdaptingPruner.class);
-
- UintAdaptingPruner(final DataSchemaContextTree tree) {
- super(tree);
- }
-
- @Override
- public ReusableNormalizedNodePruner duplicate() {
- return new UintAdaptingPruner(getTree());
- }
-
- @Override
- Object translateScalar(final DataSchemaContextNode<?> context, final Object value) throws IOException {
- final DataSchemaNode schema = context.getDataSchemaNode();
- if (schema instanceof TypedDataSchemaNode) {
- final TypeDefinition<?> type = ((TypedDataSchemaNode) schema).getType();
- if (value instanceof Short && type instanceof Uint8TypeDefinition) {
- LOG.trace("Translating legacy uint8 {}", value);
- return Uint8.valueOf((Short) value);
- } else if (value instanceof Integer && type instanceof Uint16TypeDefinition) {
- LOG.trace("Translating legacy uint16 {}", value);
- return Uint16.valueOf((Integer) value);
- } else if (value instanceof Long && type instanceof Uint32TypeDefinition) {
- LOG.trace("Translating legacy uint32 {}", value);
- return Uint32.valueOf((Long) value);
- } else if (value instanceof BigInteger && type instanceof Uint64TypeDefinition) {
- LOG.trace("Translating legacy uint64 {}", value);
- return Uint64.valueOf((BigInteger) value);
- }
- }
- return value;
- }
- }
-
ReusableNormalizedNodePruner(final SchemaContext schemaContext) {
super(schemaContext);
}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.controller.cluster.datastore.node.utils.transformer;
+
+import static com.google.common.base.Verify.verify;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.function.Function;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.impl.schema.ReusableImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class UintAdaptingPruner extends ReusableNormalizedNodePruner {
+ @FunctionalInterface
+ private interface NipAdapter extends Function<NodeIdentifierWithPredicates, NodeIdentifierWithPredicates> {
+
+ }
+
+ private enum ValueAdapter implements Function<Object, Object> {
+ UINT8 {
+ @Override
+ public Object apply(final Object obj) {
+ if (obj instanceof Short) {
+ LOG.trace("Translating legacy uint8 {}", obj);
+ return Uint8.valueOf((Short) obj);
+ }
+ return obj;
+ }
+ },
+ UINT16 {
+ @Override
+ public Object apply(final Object obj) {
+ if (obj instanceof Integer) {
+ LOG.trace("Translating legacy uint16 {}", obj);
+ return Uint16.valueOf((Integer) obj);
+ }
+ return obj;
+ }
+ },
+ UINT32 {
+ @Override
+ public Object apply(final Object obj) {
+ if (obj instanceof Long) {
+ LOG.trace("Translating legacy uint32 {}", obj);
+ return Uint32.valueOf((Long) obj);
+ }
+ return obj;
+ }
+ },
+ UINT64 {
+ @Override
+ public Object apply(final Object obj) {
+ if (obj instanceof BigInteger) {
+ LOG.trace("Translating legacy uint64 {}", obj);
+ return Uint64.valueOf((BigInteger) obj);
+ }
+ return obj;
+ }
+ };
+
+ private static final Logger LOG = LoggerFactory.getLogger(ValueAdapter.class);
+
+ static @Nullable ValueAdapter forType(final TypeDefinition<?> type) {
+ if (type instanceof Uint8TypeDefinition) {
+ return UINT8;
+ } else if (type instanceof Uint16TypeDefinition) {
+ return UINT16;
+ } else if (type instanceof Uint32TypeDefinition) {
+ return UINT32;
+ } else if (type instanceof Uint64TypeDefinition) {
+ return UINT64;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private static final LoadingCache<ListSchemaNode, NipAdapter> NIP_ADAPTERS = CacheBuilder.newBuilder()
+ .weakKeys().build(new AdapterCacheLoader());
+
+ UintAdaptingPruner(final DataSchemaContextTree tree) {
+ super(tree);
+ }
+
+ @Override
+ public ReusableNormalizedNodePruner duplicate() {
+ return new UintAdaptingPruner(getTree());
+ }
+
+ @Override
+ public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint)
+ throws IOException {
+ enter(this::adaptEntry, identifier, childSizeHint);
+ }
+
+ @Override
+ public void startLeafSetEntryNode(final NodeWithValue<?> name) throws IOException {
+ enter(this::adaptEntry, name);
+ }
+
+ @Override
+ Object translateScalar(final DataSchemaContextNode<?> context, final Object value) throws IOException {
+ final DataSchemaNode schema = context.getDataSchemaNode();
+ return schema instanceof TypedDataSchemaNode ? adaptValue(((TypedDataSchemaNode) schema).getType(), value)
+ : value;
+ }
+
+ private void adaptEntry(final ReusableImmutableNormalizedNodeStreamWriter writer, final NodeWithValue<?> name) {
+ final NodeWithValue<?> adapted;
+ final DataSchemaNode schema = currentSchema().getDataSchemaNode();
+ if (schema instanceof TypedDataSchemaNode) {
+ final Object oldValue = name.getValue();
+ final Object newValue = adaptValue(((TypedDataSchemaNode) schema).getType(), oldValue);
+ adapted = newValue == oldValue ? name : new NodeWithValue<>(name.getNodeType(), newValue);
+ } else {
+ adapted = name;
+ }
+
+ writer.startLeafSetEntryNode(adapted);
+ }
+
+ private void adaptEntry(final ReusableImmutableNormalizedNodeStreamWriter writer,
+ final NodeIdentifierWithPredicates name, final int size) {
+ final NodeIdentifierWithPredicates adapted;
+ final DataSchemaNode schema = currentSchema().getDataSchemaNode();
+ if (schema instanceof ListSchemaNode) {
+ adapted = NIP_ADAPTERS.getUnchecked((ListSchemaNode) schema).apply(name);
+ } else {
+ adapted = name;
+ }
+
+ writer.startMapEntryNode(adapted, size);
+ }
+
+ private static Object adaptValue(final TypeDefinition<?> type, final Object value) {
+ final ValueAdapter adapter = ValueAdapter.forType(type);
+ return adapter != null ? adapter.apply(value) : value;
+ }
+
+ private static final class AdapterCacheLoader extends CacheLoader<ListSchemaNode, NipAdapter> {
+ @Override
+ public NipAdapter load(final ListSchemaNode key) {
+ final Map<QName, ValueAdapter> adapters = new HashMap<>();
+
+ for (QName qname : key.getKeyDefinition()) {
+ final DataSchemaNode child;
+ try {
+ child = key.findDataTreeChild(qname).orElseThrow();
+ } catch (NoSuchElementException e) {
+ throw new IllegalStateException("Failed to find child " + qname, e);
+ }
+
+ verify(child instanceof LeafSchemaNode, "Key references non-leaf child %s", child);
+ final ValueAdapter adapter = ValueAdapter.forType(((LeafSchemaNode) child).getType());
+ if (adapter != null) {
+ adapters.put(qname, adapter);
+ }
+ }
+
+ return adapters.isEmpty() ? name -> name : new TransformingNipAdapter(adapters);
+ }
+ }
+
+ private static final class TransformingNipAdapter implements NipAdapter {
+ private final ImmutableMap<QName, ValueAdapter> adapters;
+
+ TransformingNipAdapter(final Map<QName, ValueAdapter> toTransform) {
+ adapters = ImmutableMap.copyOf(toTransform);
+ }
+
+ @Override
+ public NodeIdentifierWithPredicates apply(final NodeIdentifierWithPredicates name) {
+ final Set<Entry<QName, Object>> entries = name.entrySet();
+ final ImmutableMap.Builder<QName, Object> newEntries = ImmutableMap.builderWithExpectedSize(entries.size());
+ for (Entry<QName, Object> e : entries) {
+ final QName qname = e.getKey();
+ final ValueAdapter adapter = adapters.get(qname);
+ newEntries.put(qname, adapter != null ? adapter.apply(e.getValue()) : e.getValue());
+ }
+
+ return NodeIdentifierWithPredicates.of(name.getNodeType(), newEntries.build());
+ }
+ }
+}
--- /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.controller.cluster.datastore.node.utils.transformer;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.math.BigInteger;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class UintAdaptingPrunerTest {
+ private static final QName CONT = QName.create("urn:odl-ctlr1923", "cont");
+ private static final QName LST = QName.create(CONT, "lst");
+ private static final QName LFLST8 = QName.create(CONT, "lf-lst8");
+ private static final QName LFLST16 = QName.create(CONT, "lf-lst16");
+ private static final QName LFLST32 = QName.create(CONT, "lf-lst32");
+ private static final QName LFLST64 = QName.create(CONT, "lf-lst64");
+ private static final QName A = QName.create(LST, "a");
+ private static final QName B = QName.create(LST, "b");
+ private static final QName C = QName.create(LST, "c");
+ private static final QName D = QName.create(LST, "d");
+ private static final QName E = QName.create(LST, "e");
+ private static final QName F = QName.create(LST, "f");
+ private static final QName G = QName.create(LST, "g");
+ private static final QName H = QName.create(LST, "h");
+
+ private static EffectiveModelContext CONTEXT;
+
+ @BeforeClass
+ public static void beforeClass() {
+ CONTEXT = YangParserTestUtils.parseYangResource("/odl-ctlr1923.yang");
+ }
+
+ @Test
+ public void testListTranslation() throws IOException {
+ assertEquals(Builders.mapBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LST))
+ .withChild(Builders.mapEntryBuilder()
+ .withNodeIdentifier(NodeIdentifierWithPredicates.of(LST, ImmutableMap.<QName, Object>builder()
+ .put(A, (byte) 1)
+ .put(B, (short) 1)
+ .put(C, 1)
+ .put(D, 1L)
+ .put(E, Uint8.ONE)
+ .put(F, Uint16.ONE)
+ .put(G, Uint32.ONE)
+ .put(H, Uint64.ONE)
+ .build()))
+ .withChild(ImmutableNodes.leafNode(A, (byte) 1))
+ .withChild(ImmutableNodes.leafNode(B, (short) 1))
+ .withChild(ImmutableNodes.leafNode(C, 1))
+ .withChild(ImmutableNodes.leafNode(D, 1L))
+ .withChild(ImmutableNodes.leafNode(E, Uint8.ONE))
+ .withChild(ImmutableNodes.leafNode(F, Uint16.ONE))
+ .withChild(ImmutableNodes.leafNode(G, Uint32.ONE))
+ .withChild(ImmutableNodes.leafNode(H, Uint64.ONE))
+ .build())
+ .build(),
+ prune(Builders.mapBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LST))
+ .withChild(Builders.mapEntryBuilder()
+ .withNodeIdentifier(NodeIdentifierWithPredicates.of(LST, ImmutableMap.<QName, Object>builder()
+ .put(A, (byte) 1)
+ .put(B, (short) 1)
+ .put(C, 1)
+ .put(D, 1L)
+ .put(E, (short) 1)
+ .put(F, 1)
+ .put(G, 1L)
+ .put(H, BigInteger.ONE)
+ .build()))
+ .withChild(ImmutableNodes.leafNode(A, (byte) 1))
+ .withChild(ImmutableNodes.leafNode(B, (short) 1))
+ .withChild(ImmutableNodes.leafNode(C, 1))
+ .withChild(ImmutableNodes.leafNode(D, 1L))
+ .withChild(ImmutableNodes.leafNode(E, (short) 1))
+ .withChild(ImmutableNodes.leafNode(F, 1))
+ .withChild(ImmutableNodes.leafNode(G, 1L))
+ .withChild(ImmutableNodes.leafNode(H, BigInteger.ONE))
+ .build())
+ .build()));
+ }
+
+ @Test
+ public void testContainerTranslation() throws IOException {
+ assertEquals(Builders.containerBuilder()
+ .withNodeIdentifier(new NodeIdentifier(CONT))
+ .withChild(ImmutableNodes.leafNode(A, (byte) 1))
+ .withChild(ImmutableNodes.leafNode(B, (short) 1))
+ .withChild(ImmutableNodes.leafNode(C, 1))
+ .withChild(ImmutableNodes.leafNode(D, 1L))
+ .withChild(ImmutableNodes.leafNode(E, Uint8.ONE))
+ .withChild(ImmutableNodes.leafNode(F, Uint16.ONE))
+ .withChild(ImmutableNodes.leafNode(G, Uint32.ONE))
+ .withChild(ImmutableNodes.leafNode(H, Uint64.ONE))
+ .build(),
+ prune(Builders.containerBuilder()
+ .withNodeIdentifier(new NodeIdentifier(CONT))
+ .withChild(ImmutableNodes.leafNode(A, (byte) 1))
+ .withChild(ImmutableNodes.leafNode(B, (short) 1))
+ .withChild(ImmutableNodes.leafNode(C, 1))
+ .withChild(ImmutableNodes.leafNode(D, 1L))
+ .withChild(ImmutableNodes.leafNode(E, (short) 1))
+ .withChild(ImmutableNodes.leafNode(F, 1))
+ .withChild(ImmutableNodes.leafNode(G, 1L))
+ .withChild(ImmutableNodes.leafNode(H, BigInteger.ONE))
+ .build()));
+ }
+
+ @Test
+ public void testLeafList8() throws IOException {
+ assertEquals(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST8))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST8, Uint8.ONE))
+ .withValue(Uint8.ONE)
+ .build())
+ .build(),
+ prune(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST8))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST8, (short) 1))
+ .withValue((short) 1)
+ .build())
+ .build()));
+ }
+
+ @Test
+ public void testLeafList16() throws IOException {
+ assertEquals(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST16))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST16, Uint16.ONE))
+ .withValue(Uint16.ONE)
+ .build())
+ .build(),
+ prune(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST16))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST16, 1))
+ .withValue(1)
+ .build())
+ .build()));
+ }
+
+ @Test
+ public void testLeafList32() throws IOException {
+ assertEquals(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST32))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST32, Uint32.ONE))
+ .withValue(Uint32.ONE)
+ .build())
+ .build(),
+ prune(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST32))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST32, 1L))
+ .withValue(1L)
+ .build())
+ .build()));
+ }
+
+ @Test
+ public void testLeafList64() throws IOException {
+ assertEquals(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST64))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST64, Uint64.ONE))
+ .withValue(Uint64.ONE)
+ .build())
+ .build(),
+ prune(Builders.leafSetBuilder()
+ .withNodeIdentifier(new NodeIdentifier(LFLST64))
+ .withChild(Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(new NodeWithValue<>(LFLST64, BigInteger.ONE))
+ .withValue(BigInteger.ONE)
+ .build())
+ .build()));
+ }
+
+ private static NormalizedNode<?, ?> prune(final NormalizedNode<?, ?> node) throws IOException {
+ final ReusableNormalizedNodePruner pruner = ReusableNormalizedNodePruner.forSchemaContext(CONTEXT)
+ .withUintAdaption();
+ pruner.initializeForPath(YangInstanceIdentifier.create(node.getIdentifier()));
+
+ try (NormalizedNodeWriter writer = NormalizedNodeWriter.forStreamWriter(pruner)) {
+ writer.write(node);
+ }
+ pruner.close();
+ return pruner.getResult().get();
+ }
+}
--- /dev/null
+module odl-ctrl1923 {
+ yang-version 1;
+ namespace "urn:odl-ctlr1923";
+ prefix "ctrl1923";
+
+ description "Sodium -> Magnesium uint translation";
+
+ grouping grp {
+ leaf a { type int8; }
+ leaf b { type int16; }
+ leaf c { type int32; }
+ leaf d { type int64; }
+ leaf e { type uint8; }
+ leaf f { type uint16; }
+ leaf g { type uint32; }
+ leaf h { type uint64; }
+ }
+
+ container cont {
+ uses grp;
+ }
+
+ list lst {
+ key "a b c d e f g h";
+ uses grp;
+ }
+
+ leaf-list lf-lst8 {
+ type uint8;
+ }
+
+ leaf-list lf-lst16 {
+ type uint16;
+ }
+
+ leaf-list lf-lst32 {
+ type uint32;
+ }
+
+ leaf-list lf-lst64 {
+ type uint64;
+ }
+}