import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Set;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
+import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingStreamEventWriter;
import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader;
import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader.ClassGenerator;
import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader.GeneratorResult;
-import org.opendaylight.mdsal.binding.dom.codec.util.BindingSchemaMapping;
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingSchemaMapping;
import org.opendaylight.mdsal.binding.model.api.GeneratedType;
import org.opendaylight.mdsal.binding.model.api.MethodSignature;
import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerLike;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
private static final StackManipulation END_NODE = invokeMethod(BindingStreamEventWriter.class,
"endNode");
- // startMapEntryNode(obj.key(), UNKNOWN_SIZE);
+ // startMapEntryNode(obj.key(), UNKNOWN_SIZE)
private static final StackManipulation START_MAP_ENTRY_NODE = new StackManipulation.Compound(
OBJ,
invokeMethod(Identifiable.class, "key"),
UNKNOWN_SIZE,
invokeMethod(BindingStreamEventWriter.class, "startMapEntryNode", Identifier.class, int.class));
- // startUnkeyedListItem(UNKNOWN_SIZE);
+ // startUnkeyedListItem(UNKNOWN_SIZE)
private static final StackManipulation START_UNKEYED_LIST_ITEM = new StackManipulation.Compound(
UNKNOWN_SIZE,
invokeMethod(BindingStreamEventWriter.class, "startUnkeyedListItem", int.class));
"streamLeaf", BindingStreamEventWriter.class, String.class, Object.class);
private static final StackManipulation STREAM_LEAF_LIST = invokeMethod(DataObjectStreamer.class,
"streamLeafList",
- BindingStreamEventWriter.class, String.class, List.class);
+ BindingStreamEventWriter.class, String.class, Set.class);
private static final StackManipulation STREAM_ORDERED_LEAF_LIST = invokeMethod(DataObjectStreamer.class,
"streamOrderedLeafList", BindingStreamEventWriter.class, String.class, List.class);
private static final StackManipulation STREAM_LIST = invokeMethod(DataObjectStreamer.class,
"streamOrderedMap", Class.class, DataObjectStreamer.class, DataObjectSerializerRegistry.class,
BindingStreamEventWriter.class, List.class);
- // streamAugmentations(reg, stream, obj);
+ // streamAugmentations(reg, stream, obj)
private static final StackManipulation STREAM_AUGMENTATIONS = new StackManipulation.Compound(
REG,
STREAM,
static Class<? extends DataObjectStreamer<?>> generateStreamer(final CodecClassLoader loader,
final CodecContextFactory registry, final Class<?> type) {
- final Entry<GeneratedType, WithStatus> typeAndSchema = registry.getRuntimeContext().getTypeWithSchema(type);
- final WithStatus schema = typeAndSchema.getValue();
+ final var typeAndSchema = registry.getRuntimeContext().getTypeWithSchema(type);
+ final var schema = typeAndSchema.statement();
final StackManipulation startEvent;
- if (schema instanceof ContainerSchemaNode || schema instanceof NotificationDefinition) {
+ if (schema instanceof ContainerLike || schema instanceof NotificationDefinition) {
startEvent = classUnknownSizeMethod(START_CONTAINER_NODE, type);
} else if (schema instanceof ListSchemaNode) {
startEvent = ((ListSchemaNode) schema).getKeyDefinition().isEmpty() ? START_UNKEYED_LIST_ITEM
: START_MAP_ENTRY_NODE;
} else if (schema instanceof AugmentationSchemaNode) {
- // startAugmentationNode(Foo.class);
+ // startAugmentationNode(Foo.class)
startEvent = new StackManipulation.Compound(
ClassConstant.of(Sort.describe(type).asErasure()),
START_AUGMENTATION_NODE);
}
return loader.generateClass(type, "streamer",
- new DataObjectStreamerGenerator<>(registry, typeAndSchema.getKey(), (DataNodeContainer) schema, type,
- startEvent));
+ // FIXME: cast to GeneratedType: we really should adjust getTypeWithSchema()
+ new DataObjectStreamerGenerator<>(registry, (GeneratedType) typeAndSchema.javaType(),
+ (DataNodeContainer) schema, type, startEvent));
}
@Override
}
private static ChildStream choiceChildStream(final Method getter) {
- // streamChoice(Foo.class, reg, stream, obj.getFoo());
+ // streamChoice(Foo.class, reg, stream, obj.getFoo())
return new ChildStream(
ClassConstant.of(Sort.describe(getter.getReturnType()).asErasure()),
REG,
final Class<? extends DataObject> itemClass = getter.getReturnType().asSubclass(DataObject.class);
final DataObjectStreamer<?> streamer = registry.getDataObjectSerializer(itemClass);
- // streamContainer(FooStreamer.INSTANCE, reg, stream, obj.getFoo());
+ // streamContainer(FooStreamer.INSTANCE, reg, stream, obj.getFoo())
return new ChildStream(streamer,
streamerInstance(streamer),
REG,
method = childSchema.isUserOrdered() ? STREAM_ORDERED_MAP : STREAM_MAP;
}
- // <METHOD>(Foo.class, FooStreamer.INSTACE, reg, stream, obj.getFoo());
+ // <METHOD>(Foo.class, FooStreamer.INSTACE, reg, stream, obj.getFoo())
return new ChildStream(streamer,
ClassConstant.of(Sort.describe(itemClass).asErasure()),
streamerInstance(streamer),
private static ChildStream qnameChildStream(final StackManipulation method, final Method getter,
final DataSchemaNode schema) {
- // <METHOD>(stream, "foo", obj.getFoo());
+ // <METHOD>(stream, "foo", obj.getFoo())
return new ChildStream(
STREAM,
new TextConstant(schema.getQName().getLocalName()),
}
private static StackManipulation classUnknownSizeMethod(final StackManipulation method, final Class<?> type) {
- // <METHOD>(Foo.class, UNKNOWN_SIZE);
+ // <METHOD>(Foo.class, UNKNOWN_SIZE)
return new StackManipulation.Compound(
ClassConstant.of(Sort.describe(type).asErasure()),
UNKNOWN_SIZE,
@Override
public InstrumentedType prepare(final InstrumentedType instrumentedType) {
return instrumentedType
- // private static final This INSTANCE = new This();
+ // private static final This INSTANCE = new This()
.withField(new FieldDescription.Token(INSTANCE_FIELD, PUB_CONST, instrumentedType.asGenericType()))
.withInitializer(InitializeInstanceField.INSTANCE);
}
public ByteCodeAppender appender(final Target implementationTarget) {
final List<StackManipulation> manipulations = new ArrayList<>(children.size() + 6);
- // stream.<START_EVENT>(...);
+ // stream.<START_EVENT>(...)
manipulations.add(STREAM);
manipulations.add(startEvent);
manipulations.addAll(children);
if (Augmentable.class.isAssignableFrom(bindingInterface)) {
- // streamAugmentations(reg, stream, obj);
+ // streamAugmentations(reg, stream, obj)
manipulations.add(STREAM_AUGMENTATIONS);
}
- // stream.endNode();
+ // stream.endNode()
manipulations.add(STREAM);
manipulations.add(END_NODE);
- // return;
+ // return
manipulations.add(MethodReturn.VOID);
return new ByteCodeAppender.Simple(manipulations);
private enum InitializeInstanceField implements ByteCodeAppender {
INSTANCE;
+ // TODO: eliminate this constant when ElementMatchers.isDefaultConstructor() returns a singleton
+ private static final ElementMatcher<MethodDescription> IS_DEFAULT_CONSTRUCTOR =
+ ElementMatchers.isDefaultConstructor();
+
@Override
public Size apply(final MethodVisitor methodVisitor, final Context implementationContext,
final MethodDescription instrumentedMethod) {
TypeCreation.of(instrumentedType),
Duplication.SINGLE,
MethodInvocation.invoke(instrumentedType.getDeclaredMethods()
- .filter(ElementMatchers.isDefaultConstructor()).getOnly().asDefined()),
+ .filter(IS_DEFAULT_CONSTRUCTOR).getOnly().asDefined()),
putField(instrumentedType, INSTANCE_FIELD))
.apply(methodVisitor, implementationContext);
return new Size(operandStackSize.getMaximalSize(), instrumentedMethod.getStackSize());