Deserialize annotations on class members

Make 'Callable' message of descriptors.proto extensible, extend it in
java_descriptors.proto with a JVM signature of the member. This is needed in
order for annotation deserializer to find out which member in the compiled
bytecode corresponds to which descriptor in the hierarchy.

Create a new module 'serialization.java' containing everything related to
Java-specific serialization of descriptors.

Add an extension point to DescriptorSerializer, allowing to perform
platform-specific serialization on a callable
This commit is contained in:
Alexander Udalov
2013-07-05 22:38:46 +04:00
parent d0635aac3e
commit 67ca7b78c4
26 changed files with 368 additions and 99 deletions
@@ -196,6 +196,8 @@ message Callable {
repeated ValueParameter value_parameter = 7;
required Type return_type = 8;
extensions 100 to 199;
}
enum Modality {
@@ -16,6 +16,7 @@
package org.jetbrains.jet.descriptors.serialization;
import com.google.protobuf.ExtensionRegistryLite;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.utils.ExceptionUtils;
@@ -24,11 +25,11 @@ import java.io.IOException;
public final class ClassData {
@NotNull
public static ClassData read(@NotNull byte[] bytes) {
public static ClassData read(@NotNull byte[] bytes, @NotNull ExtensionRegistryLite registry) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
NameResolver nameResolver = NameSerializationUtil.deserializeNameResolver(in);
ProtoBuf.Class classProto = ProtoBuf.Class.parseFrom(in);
ProtoBuf.Class classProto = ProtoBuf.Class.parseFrom(in, registry);
return new ClassData(nameResolver, classProto);
}
catch (IOException e) {
@@ -169,7 +169,7 @@ public class DescriptorDeserializer {
boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
if (isNotDefault) {
setter = new PropertySetterDescriptorImpl(
property, getSetterAnnotations(proto, setterFlags),
property, getAnnotations(proto, setterFlags),
modality(Flags.MODALITY.get(setterFlags)), visibility(Flags.VISIBILITY.get(setterFlags)),
isNotDefault, !isNotDefault, property.getKind()
);
@@ -192,13 +192,11 @@ public class DescriptorDeserializer {
private PropertyDescriptorImpl createPropertyDescriptor(@NotNull Callable proto) {
int flags = proto.getFlags();
Name name = nameResolver.getName(proto.getName());
List<AnnotationDescriptor> annotations = getAnnotations(proto);
List<AnnotationDescriptor> annotations = getAnnotations(proto, proto.getFlags());
Visibility visibility = visibility(Flags.VISIBILITY.get(flags));
Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(flags);
if (callableKind == Callable.CallableKind.OBJECT_PROPERTY) {
assert containingDeclaration instanceof ClassOrNamespaceDescriptor
: "Properties for objects can only exist in class or namespace: " + name;
FqNameUnsafe fqName = DescriptorUtils.getFQName(containingDeclaration).child(name);
ClassId objectId = ClassId.fromFqNameAndContainingDeclaration(fqName, (ClassOrNamespaceDescriptor) containingDeclaration);
ClassDescriptor objectClass = typeDeserializer.getDescriptorFinder().findClass(objectId);
@@ -223,7 +221,7 @@ public class DescriptorDeserializer {
int flags = proto.getFlags();
SimpleFunctionDescriptorImpl function = new SimpleFunctionDescriptorImpl(
containingDeclaration,
getAnnotations(proto),
getAnnotations(proto, proto.getFlags()),
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags))
);
@@ -254,7 +252,7 @@ public class DescriptorDeserializer {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
ConstructorDescriptorImpl descriptor = new ConstructorDescriptorImpl(
classDescriptor,
getAnnotations(proto),
getAnnotations(proto, proto.getFlags()),
// TODO: primary
true);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
@@ -269,17 +267,15 @@ public class DescriptorDeserializer {
return descriptor;
}
private List<AnnotationDescriptor> getAnnotations(Callable proto) {
return Flags.HAS_ANNOTATIONS.get(proto.getFlags())
? annotationDeserializer.loadCallableAnnotations(proto)
@NotNull
private List<AnnotationDescriptor> getAnnotations(@NotNull Callable proto, int flags) {
assert containingDeclaration instanceof ClassOrNamespaceDescriptor
: "Only members in classes or namespaces should be serialized: " + containingDeclaration;
return Flags.HAS_ANNOTATIONS.get(flags)
? annotationDeserializer.loadCallableAnnotations((ClassOrNamespaceDescriptor) containingDeclaration, proto)
: Collections.<AnnotationDescriptor>emptyList();
}
private List<AnnotationDescriptor> getSetterAnnotations(Callable proto, int setterFlags) {
return Flags.HAS_ANNOTATIONS.get(setterFlags) ? annotationDeserializer.loadSetterAnnotations(proto) : Collections
.<AnnotationDescriptor>emptyList();
}
private static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
switch (memberKind) {
case DECLARATION:
@@ -212,6 +212,8 @@ public class DescriptorSerializer {
builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType())));
extension.serializeCallable(descriptor, builder);
return builder;
}
@@ -5262,8 +5262,9 @@ public final class ProtoBuf {
// @@protoc_insertion_point(class_scope:org.jetbrains.jet.descriptors.serialization.Package)
}
public interface CallableOrBuilder
extends com.google.protobuf.MessageLiteOrBuilder {
public interface CallableOrBuilder extends
com.google.protobuf.GeneratedMessageLite.
ExtendableMessageOrBuilder<Callable> {
// optional int32 flags = 1;
boolean hasFlags();
@@ -5310,8 +5311,8 @@ public final class ProtoBuf {
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Type getReturnType();
}
public static final class Callable extends
com.google.protobuf.GeneratedMessageLite
implements CallableOrBuilder {
com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
Callable> implements CallableOrBuilder {
// Use Callable.newBuilder() to construct.
private Callable(Builder builder) {
super(builder);
@@ -6158,6 +6159,10 @@ public final class ProtoBuf {
memoizedIsInitialized = 0;
return false;
}
if (!extensionsAreInitialized()) {
memoizedIsInitialized = 0;
return false;
}
memoizedIsInitialized = 1;
return true;
}
@@ -6165,6 +6170,9 @@ public final class ProtoBuf {
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
com.google.protobuf.GeneratedMessageLite
.ExtendableMessage<org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable>.ExtensionWriter extensionWriter =
newExtensionWriter();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeInt32(1, flags_);
}
@@ -6195,6 +6203,7 @@ public final class ProtoBuf {
if (((bitField0_ & 0x00000010) == 0x00000010)) {
output.writeInt32(11, setterParameterName_);
}
extensionWriter.writeUntil(200, output);
}
private int memoizedSerializedSize = -1;
@@ -6243,6 +6252,7 @@ public final class ProtoBuf {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(11, setterParameterName_);
}
size += extensionsSerializedSize();
memoizedSerializedSize = size;
return size;
}
@@ -6329,9 +6339,8 @@ public final class ProtoBuf {
public Builder toBuilder() { return newBuilder(this); }
public static final class Builder extends
com.google.protobuf.GeneratedMessageLite.Builder<
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable, Builder>
implements org.jetbrains.jet.descriptors.serialization.ProtoBuf.CallableOrBuilder {
com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable, Builder> implements org.jetbrains.jet.descriptors.serialization.ProtoBuf.CallableOrBuilder {
// Construct using org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
@@ -6490,6 +6499,7 @@ public final class ProtoBuf {
if (other.hasReturnType()) {
mergeReturnType(other.getReturnType());
}
this.mergeExtensionFields(other);
return this;
}
@@ -6524,6 +6534,10 @@ public final class ProtoBuf {
return false;
}
if (!extensionsAreInitialized()) {
return false;
}
return true;
}
@@ -17,6 +17,7 @@
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
public abstract class SerializerExtension {
@@ -25,4 +26,7 @@ public abstract class SerializerExtension {
public boolean hasSupertypes(@NotNull ClassDescriptor descriptor) {
return true;
}
public void serializeCallable(@NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto) {
}
}
@@ -3,6 +3,7 @@ package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import java.util.List;
@@ -18,22 +19,14 @@ public interface AnnotationDeserializer {
@NotNull
@Override
public List<AnnotationDescriptor> loadCallableAnnotations(
@NotNull ProtoBuf.Callable callableProto
@NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto
) {
return notSupported();
}
@NotNull
@Override
public List<AnnotationDescriptor> loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
return notSupported();
}
@NotNull
@Override
public List<AnnotationDescriptor> loadValueParameterAnnotations(
@NotNull ProtoBuf.Callable.ValueParameter parameterProto
) {
public List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
return notSupported();
}
@@ -47,14 +40,10 @@ public interface AnnotationDeserializer {
@NotNull
List<AnnotationDescriptor> loadCallableAnnotations(
@NotNull ClassOrNamespaceDescriptor container,
@NotNull ProtoBuf.Callable callableProto
);
@NotNull
List<AnnotationDescriptor> loadValueParameterAnnotations(
@NotNull ProtoBuf.Callable.ValueParameter parameterProto
);
@NotNull
List<AnnotationDescriptor> loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto);
List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto);
}