X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fgenerator%2Fimpl%2Frt%2FAbstractCompositeRuntimeType.java;h=d144120299330e2f4f01cf91949ac064cb01f57b;hb=edc1fe4610c43c79a039ce8156c143a5ee43df89;hp=85ecec6148b4279d5a04ee97cda338b8ae2ca89b;hpb=0ee55d1f9da11dd03ff05fc67d10cbcbfe63fd2c;p=mdsal.git diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/rt/AbstractCompositeRuntimeType.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/rt/AbstractCompositeRuntimeType.java index 85ecec6148..d144120299 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/rt/AbstractCompositeRuntimeType.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/rt/AbstractCompositeRuntimeType.java @@ -8,10 +8,13 @@ package org.opendaylight.mdsal.binding.generator.impl.rt; import static java.util.Objects.requireNonNull; +import static java.util.Objects.requireNonNullElse; import com.google.common.base.Functions; -import com.google.common.collect.ImmutableCollection; +import com.google.common.base.VerifyException; import com.google.common.collect.ImmutableMap; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.model.api.GeneratedType; @@ -25,8 +28,10 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStateme abstract class AbstractCompositeRuntimeType> extends AbstractRuntimeType implements CompositeRuntimeType { + private static final RuntimeType[] EMPTY = new RuntimeType[0]; + private final ImmutableMap byClass; - private final ImmutableMap bySchemaTree; + private final Object bySchemaTree; AbstractCompositeRuntimeType(final GeneratedType bindingType, final S statement, final List children) { super(bindingType, statement); @@ -36,20 +41,40 @@ abstract class AbstractCompositeRuntimeType> .map(GeneratedRuntimeType.class::cast) .collect(ImmutableMap.toImmutableMap(GeneratedRuntimeType::getIdentifier, Functions.identity())); - // Note: this may be over-sized, but we typically deal with schema tree statements, hence it is kind of accurate - final var builder = ImmutableMap.builderWithExpectedSize(children.size()); - for (var child : children) { - final var stmt = child.statement(); - if (stmt instanceof SchemaTreeEffectiveStatement) { - builder.put(((SchemaTreeEffectiveStatement)stmt).argument(), child); + final var tmp = children.stream() + .filter(child -> child.statement() instanceof SchemaTreeEffectiveStatement) + .toArray(RuntimeType[]::new); + bySchemaTree = switch (tmp.length) { + case 0 -> EMPTY; + case 1 -> tmp[0]; + default -> { + Arrays.sort(tmp, (o1, o2) -> { + final int cmp = extractQName(o1).compareTo(extractQName(o2)); + if (cmp == 0) { + throw new VerifyException("Type " + o1 + " conflicts with " + o2 + " on schema tree"); + } + return cmp; + }); + yield tmp; } - } - bySchemaTree = builder.build(); + }; } @Override public final RuntimeType schemaTreeChild(final QName qname) { - return bySchemaTree.get(requireNonNull(qname)); + if (bySchemaTree instanceof RuntimeType tmp) { + return qname.equals(tmp.statement().argument()) ? tmp : null; + } + + final var tmp = (RuntimeType[]) bySchemaTree; + // Here we are assuming that Arrays.binarySearch() accepts a null object, so as to help CHA by not introducing + // a fake RuntimeType class and the corresponding instanceof checks to side-step the statement lookup (which + // would need more faking). + // We make a slight assumption that o2 is the what we specify as a key, but can recover if it is the other way + // around. + final int offset = Arrays.binarySearch(tmp, null, + (o1, o2) -> extractQName(requireNonNullElse(o1, o2)).compareTo(qname)); + return offset < 0 ? null : tmp[offset]; } @Override @@ -57,7 +82,27 @@ abstract class AbstractCompositeRuntimeType> return byClass.get(requireNonNull(typeName)); } - final @NonNull ImmutableCollection schemaTreeChildren() { - return bySchemaTree.values(); + // Makes an assertion of all types being of specified type + @SuppressWarnings("unchecked") + final @NonNull List schemaTree(final Class expectedType) { + if (expectedType.isInstance(bySchemaTree)) { + return List.of(expectedType.cast(bySchemaTree)); + } + + final var tmp = (RuntimeType[]) bySchemaTree; + for (var item : tmp) { + if (!expectedType.isInstance(item)) { + throw new VerifyException("Unexpected schema tree child " + item); + } + } + return (List) Collections.unmodifiableList(Arrays.asList(tmp)); + } + + private static @NonNull QName extractQName(final RuntimeType type) { + final var stmt = type.statement(); + if (stmt instanceof SchemaTreeEffectiveStatement schemaTreeStmt) { + return schemaTreeStmt.argument(); + } + throw new VerifyException("Unexpected statement " + stmt + " in " + type); } -} +} \ No newline at end of file