X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fcodec%2Fimpl%2FCodecDataObjectGenerator.java;h=1c4021ca66ac2dda4b83eb6a470b88d68ca4dde0;hb=d9a9901b2b9e33685d1702cc7105509c5369625d;hp=0d3a17e1f1a970494e9e071bcfffe90c0b2e0d7c;hpb=3ec4cd3724a1dbd590e04ce495245c63e94db065;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObjectGenerator.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObjectGenerator.java index 0d3a17e1f1..1c4021ca66 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObjectGenerator.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObjectGenerator.java @@ -10,24 +10,18 @@ package org.opendaylight.mdsal.binding.dom.codec.impl; import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; -import static org.opendaylight.mdsal.binding.dom.codec.impl.ByteBuddyUtils.THIS; +import static net.bytebuddy.implementation.bytecode.member.MethodVariableAccess.loadThis; import static org.opendaylight.mdsal.binding.dom.codec.impl.ByteBuddyUtils.getField; import static org.opendaylight.mdsal.binding.dom.codec.impl.ByteBuddyUtils.invokeMethod; import static org.opendaylight.mdsal.binding.dom.codec.impl.ByteBuddyUtils.putField; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.VarHandle; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Objects; import java.util.Optional; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.field.FieldDescription; @@ -42,18 +36,16 @@ import net.bytebuddy.implementation.bytecode.ByteCodeAppender; import net.bytebuddy.implementation.bytecode.StackManipulation; import net.bytebuddy.implementation.bytecode.assign.TypeCasting; import net.bytebuddy.implementation.bytecode.constant.ClassConstant; -import net.bytebuddy.implementation.bytecode.constant.IntegerConstant; import net.bytebuddy.implementation.bytecode.constant.TextConstant; import net.bytebuddy.implementation.bytecode.member.MethodReturn; import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess; -import net.bytebuddy.jar.asm.Label; import net.bytebuddy.jar.asm.Opcodes; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.mdsal.binding.dom.codec.impl.ClassGeneratorBridge.LocalNameProvider; import org.opendaylight.mdsal.binding.dom.codec.impl.ClassGeneratorBridge.NodeContextSupplierProvider; -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.impl.loader.CodecClassLoader; +import org.opendaylight.mdsal.binding.dom.codec.impl.loader.CodecClassLoader.ClassGenerator; +import org.opendaylight.mdsal.binding.dom.codec.impl.loader.CodecClassLoader.GeneratorResult; import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; @@ -90,7 +82,7 @@ import org.slf4j.LoggerFactory; * private static final VarHandle getBar$$$V; * private volatile Object getBar; * - * public Foo$$$codecImpl(NormalizedNodeContainer data) { + * public Foo$$$codecImpl(DistinctNodeContainer data) { * super(data); * } * @@ -160,8 +152,8 @@ import org.slf4j.LoggerFactory; */ abstract class CodecDataObjectGenerator> implements ClassGenerator { // Not reusable definition: we can inline NodeContextSuppliers without a problem - // FIXME: 6.0.0: wire this implementation, which requires that BindingRuntimeTypes provides information about types - // being generated from within a grouping + // FIXME: MDSAL-443: wire this implementation, which requires that BindingRuntimeTypes provides information about + // types being generated from within a grouping private static final class Fixed> extends CodecDataObjectGenerator implements NodeContextSupplierProvider { private final ImmutableMap properties; @@ -185,11 +177,6 @@ abstract class CodecDataObjectGenerator> implements return tmp; } - @Override - ArrayList getterMethods() { - return new ArrayList<>(properties.keySet()); - } - @Override public NodeContextSupplier resolveNodeContextSupplier(final String methodName) { final Optional> found = properties.entrySet().stream() @@ -234,14 +221,6 @@ abstract class CodecDataObjectGenerator> implements return tmp; } - @Override - ArrayList getterMethods() { - final ArrayList ret = new ArrayList<>(simpleProperties.size() + daoProperties.size()); - ret.addAll(simpleProperties.keySet()); - ret.addAll(daoProperties.keySet()); - return ret; - } - @Override public String resolveLocalName(final String methodName) { final Optional> found = simpleProperties.entrySet().stream() @@ -253,17 +232,12 @@ abstract class CodecDataObjectGenerator> implements private static final Logger LOG = LoggerFactory.getLogger(CodecDataObjectGenerator.class); private static final Generic BB_BOOLEAN = TypeDefinition.Sort.describe(boolean.class); - private static final Generic BB_DATAOBJECT = TypeDefinition.Sort.describe(DataObject.class); + private static final Generic BB_OBJECT = TypeDefinition.Sort.describe(Object.class); private static final Generic BB_INT = TypeDefinition.Sort.describe(int.class); private static final Generic BB_STRING = TypeDefinition.Sort.describe(String.class); private static final TypeDescription BB_CDO = ForLoadedType.of(CodecDataObject.class); private static final TypeDescription BB_ACDO = ForLoadedType.of(AugmentableCodecDataObject.class); - private static final Comparator METHOD_BY_ALPHABET = Comparator.comparing(Method::getName); - private static final StackManipulation ARRAYS_EQUALS = invokeMethod(Arrays.class, "equals", - byte[].class, byte[].class); - private static final StackManipulation OBJECTS_EQUALS = invokeMethod(Objects.class, "equals", - Object.class, Object.class); private static final StackManipulation FIRST_ARG_REF = MethodVariableAccess.REFERENCE.loadFrom(1); private static final int PROT_FINAL = Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC; @@ -302,7 +276,7 @@ abstract class CodecDataObjectGenerator> implements final Generic bindingDef = TypeDefinition.Sort.describe(bindingInterface); @SuppressWarnings("unchecked") Builder builder = (Builder) BB.subclass(Generic.Builder.parameterizedType(superClass, bindingDef).build()) - .visit(ByteBuddyUtils.computeFrames()).name(fqcn).implement(bindingDef); + .name(fqcn).implement(bindingDef); builder = generateGetters(builder); @@ -314,23 +288,14 @@ abstract class CodecDataObjectGenerator> implements new KeyMethodImplementation(methodName, retType)); } - // Index all property methods, turning them into "getFoo()" invocations, retaining order. We will be using - // those invocations in each of the three methods. Note that we do not glue the invocations to 'this', as we - // will be invoking them on 'other' in codecEquals() - final ArrayList properties = getterMethods(); - // Make sure properties are alpha-sorted - properties.sort(METHOD_BY_ALPHABET); - final ImmutableMap methods = Maps.uniqueIndex(properties, - ByteBuddyUtils::invokeMethod); - // Final bits: return GeneratorResult.of(builder // codecHashCode() ... .defineMethod("codecHashCode", BB_INT, PROT_FINAL) .intercept(codecHashCode(bindingInterface)) - // ... codecEquals() ... - .defineMethod("codecEquals", BB_BOOLEAN, PROT_FINAL).withParameter(BB_DATAOBJECT) - .intercept(codecEquals(methods)) + // ... equals(Object) ... + .defineMethod("codecEquals", BB_BOOLEAN, PROT_FINAL).withParameter(BB_OBJECT) + .intercept(codecEquals(bindingInterface)) // ... toString() ... .defineMethod("toString", BB_STRING, PUB_FINAL) .intercept(toString(bindingInterface)) @@ -340,50 +305,27 @@ abstract class CodecDataObjectGenerator> implements abstract Builder generateGetters(Builder builder); - abstract ArrayList getterMethods(); - - private static Implementation codecEquals(final ImmutableMap properties) { - // Label for 'return false;' - final Label falseLabel = new Label(); - // Condition for 'if (!...)' - final StackManipulation ifFalse = ByteBuddyUtils.ifEq(falseLabel); - - final List manipulations = new ArrayList<>(properties.size() * 6 + 5); - for (Entry entry : properties.entrySet()) { - // if (!java.util.(Objects|Arrays).equals(getFoo(), other.getFoo())) { - // return false; - // } - manipulations.add(THIS); - manipulations.add(entry.getKey()); - manipulations.add(FIRST_ARG_REF); - manipulations.add(entry.getKey()); - manipulations.add(entry.getValue().getReturnType().isArray() ? ARRAYS_EQUALS : OBJECTS_EQUALS); - manipulations.add(ifFalse); - } - - // return true; - manipulations.add(IntegerConstant.ONE); - manipulations.add(MethodReturn.INTEGER); - // L0: return false; - manipulations.add(ByteBuddyUtils.markLabel(falseLabel)); - manipulations.add(IntegerConstant.ZERO); - manipulations.add(MethodReturn.INTEGER); - - return new Implementation.Simple(manipulations.toArray(new StackManipulation[0])); - } - private static Implementation codecHashCode(final Class bindingInterface) { return new Implementation.Simple( // return Foo.bindingHashCode(this); - THIS, + loadThis(), invokeMethod(bindingInterface, BindingMapping.BINDING_HASHCODE_NAME, bindingInterface), MethodReturn.INTEGER); } + private static Implementation codecEquals(final Class bindingInterface) { + return new Implementation.Simple( + // return Foo.bindingEquals(this, obj); + loadThis(), + FIRST_ARG_REF, + invokeMethod(bindingInterface, BindingMapping.BINDING_EQUALS_NAME, bindingInterface, Object.class), + MethodReturn.INTEGER); + } + private static Implementation toString(final Class bindingInterface) { return new Implementation.Simple( // return Foo.bindingToString(this); - THIS, + loadThis(), invokeMethod(bindingInterface, BindingMapping.BINDING_TO_STRING_NAME, bindingInterface), MethodReturn.REFERENCE); } @@ -444,7 +386,7 @@ abstract class CodecDataObjectGenerator> implements public ByteCodeAppender appender(final Target implementationTarget) { return new ByteCodeAppender.Simple( // return (FooType) codecKey(getFoo$$$V); - THIS, + loadThis(), getField(implementationTarget.getInstrumentedType(), handleName), CODEC_KEY, TypeCasting.to(retType), @@ -492,7 +434,7 @@ abstract class CodecDataObjectGenerator> implements final TypeDescription instrumentedType = implementationTarget.getInstrumentedType(); return new ByteCodeAppender.Simple( // return (FooType) codecMember(getFoo$$$V, getFoo$$$S); - THIS, + loadThis(), getField(instrumentedType, handleName), getField(instrumentedType, stringName), CODEC_MEMBER, @@ -517,7 +459,7 @@ abstract class CodecDataObjectGenerator> implements public ByteCodeAppender appender(final Target implementationTarget) { return new ByteCodeAppender.Simple( // return (FooType) codecMember(getFoo$$$V, FooType.class); - THIS, + loadThis(), getField(implementationTarget.getInstrumentedType(), handleName), ClassConstant.of(TypeDefinition.Sort.describe(bindingClass).asErasure()), CODEC_MEMBER, @@ -559,7 +501,7 @@ abstract class CodecDataObjectGenerator> implements final TypeDescription instrumentedType = implementationTarget.getInstrumentedType(); return new ByteCodeAppender.Simple( // return (FooType) codecMember(getFoo$$$V, getFoo$$$C); - THIS, + loadThis(), getField(instrumentedType, handleName), getField(instrumentedType, contextName), CODEC_MEMBER,