*/
package org.opendaylight.mdsal.binding.generator.impl.reactor;
-import com.google.common.collect.Iterables;
-import java.util.ArrayList;
+import static com.google.common.base.Verify.verify;
+
+import com.google.common.collect.ImmutableList;
import java.util.List;
-import org.opendaylight.mdsal.binding.generator.impl.rt.DerivedChoiceRuntimeType;
-import org.opendaylight.mdsal.binding.generator.impl.rt.OriginalChoiceRuntimeType;
+import org.opendaylight.mdsal.binding.generator.impl.rt.DefaultChoiceRuntimeType;
import org.opendaylight.mdsal.binding.model.api.GeneratedType;
import org.opendaylight.mdsal.binding.model.api.Type;
import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.RuntimeType;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
* Generator corresponding to a {@code choice} statement.
*/
final class ChoiceGenerator extends CompositeSchemaTreeGenerator<ChoiceEffectiveStatement, ChoiceRuntimeType> {
+ static final class ChoiceBuilder extends CompositeRuntimeTypeBuilder<ChoiceEffectiveStatement, ChoiceRuntimeType> {
+ private ImmutableList<CaseRuntimeType> augmentedCases;
+
+ ChoiceBuilder(final ChoiceEffectiveStatement statement) {
+ super(statement);
+ }
+
+ @Override
+ CompositeRuntimeTypeBuilder<ChoiceEffectiveStatement, ChoiceRuntimeType> fillTypes(
+ final ChildLookup lookup,
+ final AbstractCompositeGenerator<ChoiceEffectiveStatement, ChoiceRuntimeType> generator) {
+ fillAugmentedCases(lookup, generator.augments());
+ return super.fillTypes(lookup, generator);
+ }
+
+ @Override
+ boolean isAugmentedChild(final ChildLookup lookup, final QName qname) {
+ for (var augmented : augmentedCases) {
+ if (qname.equals(augmented.statement().argument())) {
+ return true;
+ }
+ }
+ return super.isAugmentedChild(lookup, qname);
+ }
+
+ @Override
+ ChoiceRuntimeType build(final GeneratedType type, final ChoiceEffectiveStatement statement,
+ final List<RuntimeType> children, final List<AugmentRuntimeType> augments) {
+ verify(augments.isEmpty(), "Unexpected augments %s", augments);
+ children.addAll(augmentedCases);
+ return new DefaultChoiceRuntimeType(type, statement, children);
+ }
+
+ private void fillAugmentedCases(final ChildLookup lookup, final List<AbstractAugmentGenerator> augments) {
+ final var builder = ImmutableList.<CaseRuntimeType>builder();
+ for (var augment : augments) {
+ builder.addAll(augment.augmentedCasesIn(lookup, statement()));
+ }
+ augmentedCases = builder.build();
+ }
+ }
+
ChoiceGenerator(final ChoiceEffectiveStatement statement, final AbstractCompositeGenerator<?, ?> parent) {
super(statement, parent);
}
}
@Override
- ChoiceRuntimeType createRuntimeType(final GeneratedType type, final ChoiceEffectiveStatement statement,
- final List<RuntimeType> children, final List<AugmentRuntimeType> augments) {
- final var original = getOriginal();
- if (!statement.equals(original.statement())) {
- return new DerivedChoiceRuntimeType(type, statement, children, augments,
- original.runtimeType().orElseThrow());
- }
-
- // Pick up any case statements added by augments which are not reflected in our children. This can happen when
- // a choice is added via uses into two different places and then augmented. Since groupings are reused, validity
- // of such use is not guarded by compile-time checks.
- //
- // Furthermore such case statements can be freely propagated via copy builders and thus can occur in unexpected
- // places. If that happens, though, the two case statements can be equivalent, e.g. by having the exact same
- // shape -- in which case Binding -> DOM translation needs to correct this mishap and play pretend the correct
- // case was used.
- final var augmentedCases = new ArrayList<CaseRuntimeType>();
- for (var augment : original.augments()) {
- for (var gen : augment) {
- if (gen instanceof CaseGenerator) {
- ((CaseGenerator) gen).runtimeType().ifPresent(augmented -> {
- for (var child : Iterables.concat(children, augmentedCases)) {
- if (child instanceof CaseRuntimeType && child.javaType().equals(augmented.javaType())) {
- return;
- }
- }
- augmentedCases.add(augmented);
- });
- }
- }
- }
-
- return new OriginalChoiceRuntimeType(type, statement, children, augments, augmentedCases);
+ ChoiceBuilder createBuilder(final ChoiceEffectiveStatement statement) {
+ return new ChoiceBuilder(statement);
}
}