2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.binding.generator.impl.rt;
10 import static com.google.common.base.Verify.verify;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.base.Functions;
14 import com.google.common.collect.ImmutableMap;
15 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.List;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
21 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
22 import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
23 import org.opendaylight.mdsal.binding.runtime.api.GeneratedRuntimeType;
24 import org.opendaylight.mdsal.binding.runtime.api.RuntimeType;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
29 abstract class AbstractCompositeRuntimeType<S extends EffectiveStatement<?, ?>>
30 extends AbstractRuntimeType<S, GeneratedType> implements CompositeRuntimeType {
31 private static final RuntimeType[] EMPTY = new RuntimeType[0];
33 private final ImmutableMap<JavaTypeName, GeneratedRuntimeType> byClass;
34 private final Object bySchemaTree;
36 @SuppressFBWarnings(value = "SE_COMPARATOR_SHOULD_BE_SERIALIZABLE",
37 justification = "https://github.com/spotbugs/spotbugs/issues/1985")
38 AbstractCompositeRuntimeType(final GeneratedType bindingType, final S statement, final List<RuntimeType> children) {
39 super(bindingType, statement);
41 byClass = children.stream()
42 .filter(GeneratedRuntimeType.class::isInstance)
43 .map(GeneratedRuntimeType.class::cast)
44 .collect(ImmutableMap.toImmutableMap(GeneratedRuntimeType::getIdentifier, Functions.identity()));
46 final var tmp = children.stream()
47 .filter(child -> child.statement() instanceof SchemaTreeEffectiveStatement)
48 .toArray(RuntimeType[]::new);
54 bySchemaTree = tmp[0];
57 Arrays.sort(tmp, (o1, o2) -> {
58 final int cmp = extractQName(o1).compareTo(extractQName(o2));
59 verify(cmp != 0, "Type %s conflicts with %s on schema tree", o1, o2);
67 public final RuntimeType schemaTreeChild(final QName qname) {
68 if (bySchemaTree instanceof RuntimeType) {
69 final var tmp = (RuntimeType) bySchemaTree;
70 return qname.equals(tmp.statement().argument()) ? tmp : null;
73 final var tmp = (RuntimeType[]) bySchemaTree;
74 @SuppressFBWarnings(value = "SE_COMPARATOR_SHOULD_BE_SERIALIZABLE",
75 justification = "https://github.com/spotbugs/spotbugs/issues/1985")
76 final int offset = Arrays.binarySearch(tmp, null, (o1, o2) -> {
77 // We make assumptions about how Arrays.binarySearch() is implemented: o2 is expected to be the provided
78 // key -- which is null. This helps CHA by not introducing a fake RuntimeType class and the
79 // corresponding instanceof checks.
80 verify(o2 == null, "Unexpected key %s", o2);
81 return extractQName(o1).compareTo(qname);
83 return offset < 0 ? null : tmp[offset];
87 public final GeneratedRuntimeType bindingChild(final JavaTypeName typeName) {
88 return byClass.get(requireNonNull(typeName));
91 // Makes an assertion of all types being of specified type
92 @SuppressWarnings("unchecked")
93 final <T extends RuntimeType> @NonNull List<T> schemaTree(final Class<T> expectedType) {
94 if (expectedType.isInstance(bySchemaTree)) {
95 return List.of(expectedType.cast(bySchemaTree));
98 final var tmp = (RuntimeType[]) bySchemaTree;
99 for (var item : tmp) {
100 verify(expectedType.isInstance(item), "Unexpected schema tree child %s", item);
102 return (List<T>) Collections.unmodifiableList(Arrays.asList(tmp));
105 private static @NonNull QName extractQName(final RuntimeType type) {
106 final var stmt = type.statement();
107 verify(stmt instanceof SchemaTreeEffectiveStatement, "Unexpected statement %s in %s", stmt, type);
108 return ((SchemaTreeEffectiveStatement<?>) stmt).argument();