
io.opentelemetry.javaagent.tooling.field.FieldAccessorInterfacesGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-javaagent-tooling Show documentation
Show all versions of opentelemetry-javaagent-tooling Show documentation
Instrumentation of Java libraries using OpenTelemetry.
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.tooling.field;
import static io.opentelemetry.javaagent.tooling.field.GeneratedVirtualFieldNames.getFieldAccessorInterfaceName;
import static io.opentelemetry.javaagent.tooling.field.GeneratedVirtualFieldNames.getRealGetterName;
import static io.opentelemetry.javaagent.tooling.field.GeneratedVirtualFieldNames.getRealSetterName;
import io.opentelemetry.javaagent.bootstrap.VirtualFieldAccessorMarker;
import io.opentelemetry.javaagent.tooling.muzzle.VirtualFieldMappings;
import java.util.HashMap;
import java.util.Map;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.modifier.SyntheticState;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
final class FieldAccessorInterfacesGenerator {
private final ByteBuddy byteBuddy;
FieldAccessorInterfacesGenerator(ByteBuddy byteBuddy) {
this.byteBuddy = byteBuddy;
}
FieldAccessorInterfaces generateFieldAccessorInterfaces(
VirtualFieldMappings virtualFieldMappings) {
Map> fieldAccessorInterfaces =
new HashMap<>(virtualFieldMappings.size());
for (Map.Entry entry : virtualFieldMappings.entrySet()) {
DynamicType.Unloaded> type = makeFieldAccessorInterface(entry.getKey(), entry.getValue());
fieldAccessorInterfaces.put(type.getTypeDescription().getName(), type);
}
return new FieldAccessorInterfaces(fieldAccessorInterfaces);
}
/**
* Generate an interface that provides field accessor methods for given key class name and context
* class name.
*
* @param typeName key class name
* @param fieldTypeName context class name
* @return unloaded dynamic type containing generated interface
*/
private DynamicType.Unloaded> makeFieldAccessorInterface(
String typeName, String fieldTypeName) {
// We are using Object class name instead of fieldTypeName here because this gets injected
// onto the bootstrap class loader where context class may be unavailable
TypeDescription fieldTypeDesc = TypeDescription.ForLoadedType.of(Object.class);
return byteBuddy
.makeInterface()
.merge(SyntheticState.SYNTHETIC)
.name(getFieldAccessorInterfaceName(typeName, fieldTypeName))
.implement(VirtualFieldAccessorMarker.class)
.defineMethod(
getRealGetterName(typeName, fieldTypeName),
fieldTypeDesc,
Visibility.PUBLIC,
SyntheticState.SYNTHETIC)
.withoutCode()
.defineMethod(
getRealSetterName(typeName, fieldTypeName),
TypeDescription.ForLoadedType.of(void.class),
Visibility.PUBLIC,
SyntheticState.SYNTHETIC)
.withParameter(fieldTypeDesc, "value")
.withoutCode()
.make();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy