+ return tmp.withInitializer(new ByteCodeAppender.Simple(
+ // getFoo$$$A = AtomicReferenceFieldUpdater.newUpdater(This.class, Object.class, "getFoo");
+ ClassConstant.of(tmp),
+ OBJECT_CLASS,
+ new TextConstant(methodName),
+ ARFU_NEWUPDATER,
+ putField(tmp, arfuName)));
+ }
+ }
+
+ private static final class KeyMethodImplementation extends AbstractMethodImplementation {
+ private static final StackManipulation CODEC_KEY = invokeMethod(CodecDataObject.class,
+ "codecKey", AtomicReferenceFieldUpdater.class);
+
+ KeyMethodImplementation(final String methodName, final TypeDescription retType) {
+ super(methodName, retType);
+ }
+
+ @Override
+ public ByteCodeAppender appender(final Target implementationTarget) {
+ final TypeDescription instrumentedType = implementationTarget.getInstrumentedType();
+ return new ByteCodeAppender.Simple(
+ // return (FooType) codecKey(getFoo$$$A);
+ THIS,
+ getField(instrumentedType, arfuName),
+ CODEC_KEY,
+ TypeCasting.to(retType),
+ MethodReturn.REFERENCE);
+ }
+ }
+
+ private static final class SimpleGetterMethodImplementation extends AbstractMethodImplementation {
+ private static final StackManipulation CODEC_MEMBER = invokeMethod(CodecDataObject.class,
+ "codecMember", AtomicReferenceFieldUpdater.class, String.class);
+
+ private final String localName;
+
+ SimpleGetterMethodImplementation(final String methodName, final TypeDescription retType,
+ final String localName) {
+ super(methodName, retType);
+ this.localName = requireNonNull(localName);
+ }
+
+ @Override
+ public ByteCodeAppender appender(final Target implementationTarget) {
+ final TypeDescription instrumentedType = implementationTarget.getInstrumentedType();
+ return new ByteCodeAppender.Simple(
+ // return (FooType) codecMember(getFoo$$$A, "foo");
+ THIS,
+ getField(instrumentedType, arfuName),
+ new TextConstant(localName),
+ CODEC_MEMBER,
+ TypeCasting.to(retType),
+ MethodReturn.REFERENCE);
+ }
+ }
+
+ private static final class StructuredGetterMethodImplementation extends AbstractMethodImplementation {
+ private static final StackManipulation CODEC_MEMBER = invokeMethod(CodecDataObject.class,
+ "codecMember", AtomicReferenceFieldUpdater.class, Class.class);
+
+ private final Class<?> bindingClass;
+
+ StructuredGetterMethodImplementation(final String methodName, final TypeDescription retType,
+ final Class<?> bindingClass) {
+ super(methodName, retType);
+ this.bindingClass = requireNonNull(bindingClass);
+ }
+
+ @Override
+ public ByteCodeAppender appender(final Target implementationTarget) {
+ final TypeDescription instrumentedType = implementationTarget.getInstrumentedType();
+ return new ByteCodeAppender.Simple(
+ // return (FooType) codecMember(getFoo$$$A, FooType.class);
+ THIS,
+ getField(instrumentedType, arfuName),
+ ClassConstant.of(TypeDefinition.Sort.describe(bindingClass).asErasure()),
+ CODEC_MEMBER,
+ TypeCasting.to(retType),
+ MethodReturn.REFERENCE);
+ }
+ }
+
+ private static final class SupplierGetterMethodImplementation extends AbstractMethodImplementation {
+ private static final StackManipulation CODEC_MEMBER = invokeMethod(CodecDataObject.class,
+ "codecMember", AtomicReferenceFieldUpdater.class, NodeContextSupplier.class);
+ private static final StackManipulation BRIDGE_RESOLVE = invokeMethod(CodecDataObjectBridge.class,
+ "resolve", String.class);
+ private static final Generic BB_NCS = TypeDefinition.Sort.describe(NodeContextSupplier.class);
+
+ // getFoo$$$C
+ private final String contextName;
+
+ SupplierGetterMethodImplementation(final String methodName, final TypeDescription retType) {
+ super(methodName, retType);
+ contextName = methodName + "$$$C";
+ }
+
+ @Override
+ public InstrumentedType prepare(final InstrumentedType instrumentedType) {
+ final InstrumentedType tmp = super.prepare(instrumentedType)
+ // private static final NodeContextSupplier getFoo$$$C;
+ .withField(new FieldDescription.Token(contextName, PRIV_CONST, BB_NCS));
+
+ return tmp.withInitializer(new ByteCodeAppender.Simple(
+ // getFoo$$$C = CodecDataObjectBridge.resolve("getFoo");
+ new TextConstant(methodName),
+ BRIDGE_RESOLVE,
+ putField(tmp, contextName)));