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%2FBindingRuntimeTypesFactory.java;h=49953954cc3156bee7f22173a176640b7ffa4fef;hb=refs%2Fchanges%2F45%2F98245%2F100;hp=8c5a49450416f788b0ba575d17911ea1b09bde7a;hpb=60039d4d027e172f6e1d644fb1c2fa60688c06c0;p=mdsal.git diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/BindingRuntimeTypesFactory.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/BindingRuntimeTypesFactory.java index 8c5a494504..49953954cc 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/BindingRuntimeTypesFactory.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/BindingRuntimeTypesFactory.java @@ -10,92 +10,117 @@ package org.opendaylight.mdsal.binding.generator.impl; import static com.google.common.base.Verify.verify; import com.google.common.base.Stopwatch; -import java.util.Collection; import java.util.HashMap; -import java.util.IdentityHashMap; import java.util.Map; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.generator.impl.reactor.AbstractExplicitGenerator; import org.opendaylight.mdsal.binding.generator.impl.reactor.Generator; import org.opendaylight.mdsal.binding.generator.impl.reactor.GeneratorReactor; +import org.opendaylight.mdsal.binding.generator.impl.reactor.IdentityGenerator; import org.opendaylight.mdsal.binding.generator.impl.reactor.ModuleGenerator; +import org.opendaylight.mdsal.binding.generator.impl.reactor.RpcGenerator; +import org.opendaylight.mdsal.binding.generator.impl.reactor.RpcInputGenerator; +import org.opendaylight.mdsal.binding.generator.impl.reactor.RpcOutputGenerator; import org.opendaylight.mdsal.binding.generator.impl.reactor.TypeBuilderFactory; +import org.opendaylight.mdsal.binding.generator.impl.rt.DefaultBindingRuntimeTypes; import org.opendaylight.mdsal.binding.model.api.GeneratedType; -import org.opendaylight.mdsal.binding.model.api.Type; +import org.opendaylight.mdsal.binding.model.api.JavaTypeName; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes; +import org.opendaylight.mdsal.binding.runtime.api.IdentityRuntimeType; +import org.opendaylight.mdsal.binding.runtime.api.InputRuntimeType; +import org.opendaylight.mdsal.binding.runtime.api.ModuleRuntimeType; +import org.opendaylight.mdsal.binding.runtime.api.OutputRuntimeType; +import org.opendaylight.mdsal.binding.runtime.api.RuntimeType; import org.opendaylight.yangtools.concepts.Mutable; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; -import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class BindingRuntimeTypesFactory implements Mutable { private static final Logger LOG = LoggerFactory.getLogger(BindingRuntimeTypesFactory.class); - private final Map augmentationToSchema = new HashMap<>(); - private final Map typeToSchema = new HashMap<>(); - private final Map identities = new HashMap<>(); - - // Note: we are keying through WithStatus, but these nodes compare on semantics, so equivalent schema nodes - // can result in two distinct types. We certainly need to keep them separate. - private final Map schemaToType = new IdentityHashMap<>(); + // Modules, indexed by their QNameModule + private final Map modules = new HashMap<>(); + // Identities, indexed by their QName + private final Map identities = new HashMap<>(); + // All known types, indexed by their JavaTypeName + private final Map allTypes = new HashMap<>(); + // All RpcOutputs, indexed by their RPC's QName + private final Map rpcOutputs = new HashMap<>(); + // All RpcInputs, indexed by their RPC's QName + private final Map rpcInputs = new HashMap<>(); private BindingRuntimeTypesFactory() { // Hidden on purpose } static @NonNull BindingRuntimeTypes createTypes(final @NonNull EffectiveModelContext context) { - final Collection moduleGens = new GeneratorReactor(context) - .execute(TypeBuilderFactory.runtime()) - .values(); + final var moduleGens = new GeneratorReactor(context).execute(TypeBuilderFactory.runtime()); final Stopwatch sw = Stopwatch.createStarted(); final BindingRuntimeTypesFactory factory = new BindingRuntimeTypesFactory(); - factory.indexTypes(moduleGens); + factory.indexModules(moduleGens); LOG.debug("Indexed {} generators in {}", moduleGens.size(), sw); - return new DefaultBindingRuntimeTypes(context, factory.augmentationToSchema, factory.typeToSchema, - factory.schemaToType, factory.identities); + return new DefaultBindingRuntimeTypes(context, factory.modules, factory.allTypes, factory.identities, + factory.rpcInputs, factory.rpcOutputs); } - private void indexTypes(final Iterable generators) { - for (Generator gen : generators) { - gen.generatedType().ifPresent(type -> indexType(gen, type)); - indexTypes(gen); - } - } + private void indexModules(final Map moduleGens) { + for (var entry : moduleGens.entrySet()) { + final var modGen = entry.getValue(); - private void indexType(final @NonNull Generator generator, final @NonNull GeneratedType type) { - if (generator instanceof AbstractExplicitGenerator) { - final EffectiveStatement stmt = ((AbstractExplicitGenerator) generator).statement(); - if (stmt instanceof IdentityEffectiveStatement) { - identities.put(((IdentityEffectiveStatement) stmt).argument(), type); - } else if (stmt instanceof AugmentEffectiveStatement) { - verify(stmt instanceof AugmentationSchemaNode, "Unexpected statement %s", stmt); - augmentationToSchema.put(type, (AugmentationSchemaNode) stmt); - } + // index the module's runtime type + modGen.runtimeType().ifPresent(type -> { + safePut(modules, "modules", entry.getKey(), type); + }); - final WithStatus schema; - if (stmt instanceof TypedDataSchemaNode) { - schema = ((TypedDataSchemaNode) stmt).getType(); - } else if (stmt instanceof TypedefEffectiveStatement) { - schema = ((TypedefEffectiveStatement) stmt).getTypeDefinition(); - } else if (stmt instanceof WithStatus) { - schema = (WithStatus) stmt; - } else { - return; + // index module's identities and RPC input/outputs + for (var gen : modGen) { + if (gen instanceof IdentityGenerator) { + ((IdentityGenerator) gen).runtimeType().ifPresent(identity -> { + safePut(identities, "identities", identity.statement().argument(), identity); + }); + } + // FIXME: do not collect these once we they generate a proper RuntimeType + if (gen instanceof RpcGenerator) { + final QName rpcName = ((RpcGenerator) gen).statement().argument(); + for (var subgen : gen) { + if (subgen instanceof RpcInputGenerator) { + ((RpcInputGenerator) subgen).runtimeType() + .ifPresent(input -> rpcInputs.put(rpcName, input)); + } else if (subgen instanceof RpcOutputGenerator) { + ((RpcOutputGenerator) subgen).runtimeType() + .ifPresent(output -> rpcOutputs.put(rpcName, output)); + } + } + } } + } - typeToSchema.put(type, schema); - final var prevType = schemaToType.put(schema, type); - verify(prevType == null, "Conflicting types %s and %s on %s", type, prevType, schema); + indexRuntimeTypes(moduleGens.values()); + } + + private void indexRuntimeTypes(final Iterable generators) { + for (Generator gen : generators) { + if (gen instanceof AbstractExplicitGenerator && gen.generatedType().isPresent()) { + final var type = ((AbstractExplicitGenerator) gen).runtimeType().orElseThrow(); + final var javaType = type.javaType(); + if (javaType instanceof GeneratedType) { + final var name = javaType.getIdentifier(); + final var prev = allTypes.put(name, type); + verify(prev == null || prev == type, "Conflict on runtime type mapping of %s between %s and %s", + name, prev, type); + } + } + indexRuntimeTypes(gen); } } + + private static void safePut(final Map map, final String name, final K key, final V value) { + final var prev = map.put(key, value); + verify(prev == null, "Conflict in %s, key %s conflicts on %s versus %s", name, key, prev, value); + } }