add support for compile time constant serialization

This commit is contained in:
Michael Nedzelsky
2015-01-29 18:39:54 +03:00
parent d45a1f3e44
commit df8fed096c
12 changed files with 187 additions and 24 deletions
@@ -41,6 +41,8 @@ import org.jetbrains.kotlin.load.kotlin.DeserializedResolverUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.JVMConfigurationKeys import org.jetbrains.kotlin.cli.jvm.JVMConfigurationKeys
import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
private object BuiltInsSerializerExtension : SerializerExtension() { private object BuiltInsSerializerExtension : SerializerExtension() {
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder, stringTable: StringTable) { override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder, stringTable: StringTable) {
@@ -71,6 +73,11 @@ private object BuiltInsSerializerExtension : SerializerExtension() {
for (annotation in callable.getAnnotations()) { for (annotation in callable.getAnnotations()) {
proto.addExtension(BuiltInsProtoBuf.callableAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable)) proto.addExtension(BuiltInsProtoBuf.callableAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable))
} }
val compileTimeConstant = (callable as? PropertyDescriptor)?.getCompileTimeInitializer()
if (compileTimeConstant != null && compileTimeConstant !is NullValue) {
val type = compileTimeConstant.getType(KotlinBuiltIns.getInstance())
proto.setExtension(BuiltInsProtoBuf.compileTimeValue, AnnotationSerializer.valueProto(compileTimeConstant, type, stringTable).build())
}
} }
override fun serializeValueParameter( override fun serializeValueParameter(
@@ -0,0 +1,34 @@
package test
enum class Weapon {
ROCK
PAPER
SCISSORS
}
val byteConst: Byte = 10
val shortConst: Short = 20
val intConst: Int = 30
val longConst: Long = 40
val charConst: Char = 'A'
val stringConst: String = "abcd"
val booleanConst: Boolean = true
val floatConst: Float = 2.0f
val doubleConst: Double = 3.0
val enumConst: Weapon? = Weapon.ROCK
val arrayConst: Any = byteArray(1,2)
class Class {
val byteConst: Byte = 10
val shortConst: Short = 20
val intConst: Int = 30
val longConst: Long = 40
val charConst: Char = 'A'
val stringConst: String = "abcd"
val booleanConst: Boolean = true
val floatConst: Float = 2.0f
val doubleConst: Double = 3.0
val enumConst: Weapon? = Weapon.ROCK
val arrayConst: Any = byteArray(1,2)
}
@@ -0,0 +1,81 @@
package test
internal val arrayConst: kotlin.Any = {1.toByte(), 2.toByte()}
internal val booleanConst: kotlin.Boolean = true
internal val byteConst: kotlin.Byte = 10.toByte()
internal val charConst: kotlin.Char = \u0041 ('A')
internal val doubleConst: kotlin.Double = 3.0.toDouble()
internal val enumConst: test.Weapon? = Weapon.ROCK
internal val floatConst: kotlin.Float = 2.0.toFloat()
internal val intConst: kotlin.Int = 30
internal val longConst: kotlin.Long = 40.toLong()
internal val shortConst: kotlin.Short = 20.toShort()
internal val stringConst: kotlin.String = "abcd"
internal final class Class {
public constructor Class()
internal final val arrayConst: kotlin.Any = {1.toByte(), 2.toByte()}
internal final val booleanConst: kotlin.Boolean = true
internal final val byteConst: kotlin.Byte = 10.toByte()
internal final val charConst: kotlin.Char = \u0041 ('A')
internal final val doubleConst: kotlin.Double = 3.0.toDouble()
internal final val enumConst: test.Weapon? = Weapon.ROCK
internal final val floatConst: kotlin.Float = 2.0.toFloat()
internal final val intConst: kotlin.Int = 30
internal final val longConst: kotlin.Long = 40.toLong()
internal final val shortConst: kotlin.Short = 20.toShort()
internal final val stringConst: kotlin.String = "abcd"
}
internal final enum class Weapon : kotlin.Enum<test.Weapon> {
public enum entry ROCK : test.Weapon {
private constructor ROCK()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-ROCK> : test.Weapon.ROCK {
private constructor <class-object-for-ROCK>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
}
}
public enum entry PAPER : test.Weapon {
private constructor PAPER()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-PAPER> : test.Weapon.PAPER {
private constructor <class-object-for-PAPER>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
}
}
public enum entry SCISSORS : test.Weapon {
private constructor SCISSORS()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-SCISSORS> : test.Weapon.SCISSORS {
private constructor <class-object-for-SCISSORS>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
}
}
private constructor Weapon()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Weapon
public final /*synthesized*/ fun values(): kotlin.Array<test.Weapon>
}
@@ -61,6 +61,10 @@ public class BuiltInsSerializerTest : TestCaseWithTmpdir() {
doTest("simple.kt") doTest("simple.kt")
} }
fun testCompileTimeConstants() {
doTest("compileTimeConstants.kt")
}
fun testAnnotationTargets() { fun testAnnotationTargets() {
doTest("annotationTargets.kt") doTest("annotationTargets.kt")
} }
@@ -10,6 +10,7 @@ public final class DebugBuiltInsProtoBuf {
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.className); registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.className);
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.classAnnotation); registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.classAnnotation);
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.callableAnnotation); registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.callableAnnotation);
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.compileTimeValue);
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.parameterAnnotation); registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.parameterAnnotation);
} }
public static final int CLASS_NAME_FIELD_NUMBER = 150; public static final int CLASS_NAME_FIELD_NUMBER = 150;
@@ -45,6 +46,17 @@ public final class DebugBuiltInsProtoBuf {
.newFileScopedGeneratedExtension( .newFileScopedGeneratedExtension(
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
public static final int COMPILE_TIME_VALUE_FIELD_NUMBER = 151;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Callable { ... }</code>
*/
public static final
com.google.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable,
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value> compileTimeValue = com.google.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.class,
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.getDefaultInstance());
public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150; public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150;
/** /**
* <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code> * <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code>
@@ -76,11 +88,14 @@ public final class DebugBuiltInsProtoBuf {
"tation:z\n\023callable_annotation\022,.org.jetb" + "tation:z\n\023callable_annotation\022,.org.jetb" +
"rains.kotlin.serialization.Callable\030\226\001 \003", "rains.kotlin.serialization.Callable\030\226\001 \003",
"(\0132..org.jetbrains.kotlin.serialization." + "(\0132..org.jetbrains.kotlin.serialization." +
"Annotation:\212\001\n\024parameter_annotation\022;.or" + "Annotation:\210\001\n\022compile_time_value\022,.org." +
"g.jetbrains.kotlin.serialization.Callabl" + "jetbrains.kotlin.serialization.Callable\030" +
"e.ValueParameter\030\226\001 \003(\0132..org.jetbrains." + "\227\001 \001(\0132=.org.jetbrains.kotlin.serializat" +
"kotlin.serialization.AnnotationB\027B\025Debug" + "ion.Annotation.Argument.Value:\212\001\n\024parame" +
"BuiltInsProtoBuf" "ter_annotation\022;.org.jetbrains.kotlin.se" +
"rialization.Callable.ValueParameter\030\226\001 \003" +
"(\0132..org.jetbrains.kotlin.serialization." +
"AnnotationB\027B\025DebugBuiltInsProtoBuf"
}; };
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -90,7 +105,8 @@ public final class DebugBuiltInsProtoBuf {
className.internalInit(descriptor.getExtensions().get(0)); className.internalInit(descriptor.getExtensions().get(0));
classAnnotation.internalInit(descriptor.getExtensions().get(1)); classAnnotation.internalInit(descriptor.getExtensions().get(1));
callableAnnotation.internalInit(descriptor.getExtensions().get(2)); callableAnnotation.internalInit(descriptor.getExtensions().get(2));
parameterAnnotation.internalInit(descriptor.getExtensions().get(3)); compileTimeValue.internalInit(descriptor.getExtensions().get(3));
parameterAnnotation.internalInit(descriptor.getExtensions().get(4));
return null; return null;
} }
}; };
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.Flags import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
import org.jetbrains.kotlin.types.JetType
public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>( public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
storageManager: StorageManager, storageManager: StorageManager,
@@ -130,11 +132,11 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
container: ProtoContainer, container: ProtoContainer,
proto: ProtoBuf.Callable, proto: ProtoBuf.Callable,
nameResolver: NameResolver, nameResolver: NameResolver,
kind: AnnotatedCallableKind expectedType: JetType
): C? { ): C? {
val signature = getCallableSignature(proto, nameResolver, kind) ?: return null val signature = getCallableSignature(proto, nameResolver, AnnotatedCallableKind.PROPERTY) ?: return null
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind) val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, AnnotatedCallableKind.PROPERTY)
if (kotlinClass == null) { if (kotlinClass == null) {
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName(nameResolver)}", null) errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName(nameResolver)}", null)
return null return null
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
import org.jetbrains.kotlin.types.JetType
class BuiltInsAnnotationAndConstantLoader( class BuiltInsAnnotationAndConstantLoader(
module: ModuleDescriptor module: ModuleDescriptor
@@ -61,9 +62,9 @@ class BuiltInsAnnotationAndConstantLoader(
container: ProtoContainer, container: ProtoContainer,
proto: ProtoBuf.Callable, proto: ProtoBuf.Callable,
nameResolver: NameResolver, nameResolver: NameResolver,
kind: AnnotatedCallableKind expectedType: JetType
): CompileTimeConstant<*>? { ): CompileTimeConstant<*>? {
// TODO: support deserialization of compile time constants in built-ins when needed val value = proto.getExtension(BuiltInsProtoBuf.compileTimeValue)
throw UnsupportedOperationException() return deserializer.resolveValue(expectedType, value, nameResolver)
} }
} }
+1
View File
@@ -32,6 +32,7 @@ extend Class {
extend Callable { extend Callable {
repeated Annotation callable_annotation = 150; repeated Annotation callable_annotation = 150;
optional Annotation.Argument.Value compile_time_value = 151;
} }
extend Callable.ValueParameter { extend Callable.ValueParameter {
@@ -10,6 +10,7 @@ public final class BuiltInsProtoBuf {
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.className); registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.className);
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.classAnnotation); registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.classAnnotation);
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.callableAnnotation); registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.callableAnnotation);
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.compileTimeValue);
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.parameterAnnotation); registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.parameterAnnotation);
} }
public static final int CLASS_NAME_FIELD_NUMBER = 150; public static final int CLASS_NAME_FIELD_NUMBER = 150;
@@ -57,6 +58,21 @@ public final class BuiltInsProtoBuf {
150, 150,
com.google.protobuf.WireFormat.FieldType.MESSAGE, com.google.protobuf.WireFormat.FieldType.MESSAGE,
false); false);
public static final int COMPILE_TIME_VALUE_FIELD_NUMBER = 151;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Callable { ... }</code>
*/
public static final
com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Callable,
org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value> compileTimeValue = com.google.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Callable.getDefaultInstance(),
org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.getDefaultInstance(),
org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.getDefaultInstance(),
null,
151,
com.google.protobuf.WireFormat.FieldType.MESSAGE);
public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150; public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150;
/** /**
* <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code> * <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code>
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.serialization.deserialization;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.JetType;
import java.util.List; import java.util.List;
@@ -51,6 +52,6 @@ public interface AnnotationAndConstantLoader<A, C> {
@NotNull ProtoContainer container, @NotNull ProtoContainer container,
@NotNull ProtoBuf.Callable proto, @NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver, @NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind @NotNull JetType expectedType
); );
} }
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
public class AnnotationDeserializer(private val module: ModuleDescriptor) { public class AnnotationDeserializer(private val module: ModuleDescriptor) {
private val builtIns: KotlinBuiltIns private val builtIns: KotlinBuiltIns
@@ -62,7 +63,7 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
return Pair(parameter, resolveValue(parameter.getType(), proto.getValue(), nameResolver)) return Pair(parameter, resolveValue(parameter.getType(), proto.getValue(), nameResolver))
} }
private fun resolveValue( public fun resolveValue(
expectedType: JetType, expectedType: JetType,
value: Value, value: Value,
nameResolver: NameResolver nameResolver: NameResolver
@@ -90,9 +91,7 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
AnnotationValue(deserializeAnnotation(value.getAnnotation(), nameResolver)) AnnotationValue(deserializeAnnotation(value.getAnnotation(), nameResolver))
} }
Type.ARRAY -> { Type.ARRAY -> {
if (!KotlinBuiltIns.isArray(expectedType) && val expectedIsArray = KotlinBuiltIns.isArray(expectedType) || KotlinBuiltIns.isPrimitiveArray(expectedType)
!KotlinBuiltIns.isPrimitiveArray(expectedType)) return ErrorValue.create("Unexpected argument value")
val arrayElements = value.getArrayElementList() val arrayElements = value.getArrayElementList()
val actualArrayType = val actualArrayType =
@@ -102,13 +101,13 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
builtIns.getArrayType(Variance.INVARIANT, actualElementType) builtIns.getArrayType(Variance.INVARIANT, actualElementType)
} }
else { else {
// In the case of empty array, no element has the element type, so we fall back to the expected type. // In the case of empty array, no element has the element type, so we fall back to the expected type, if any.
// This is not very accurate when annotation class has been changed without recompiling clients, // This is not very accurate when annotation class has been changed without recompiling clients,
// but should not in fact matter because the value is empty anyway // but should not in fact matter because the value is empty anyway
expectedType if (expectedIsArray) expectedType else builtIns.getArrayType(Variance.INVARIANT, builtIns.getAnyType())
} }
val expectedElementType = builtIns.getArrayElementType(expectedType) val expectedElementType = builtIns.getArrayElementType(if (expectedIsArray) expectedType else actualArrayType)
ArrayValue( ArrayValue(
arrayElements.map { resolveValue(expectedElementType, it, nameResolver) }, arrayElements.map { resolveValue(expectedElementType, it, nameResolver) },
@@ -119,12 +118,13 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
else -> error("Unsupported annotation argument type: ${value.getType()} (expected $expectedType)") else -> error("Unsupported annotation argument type: ${value.getType()} (expected $expectedType)")
} }
if (result.getType(builtIns) != expectedType) { if (result.getType(builtIns) isSubtypeOf expectedType) {
return result
}
else {
// This means that an annotation class has been changed incompatibly without recompiling clients // This means that an annotation class has been changed incompatibly without recompiling clients
return ErrorValue.create("Unexpected argument value") return ErrorValue.create("Unexpected argument value")
} }
return result
} }
// NOTE: see analogous code in BinaryClassAnnotationAndConstantLoaderImpl // NOTE: see analogous code in BinaryClassAnnotationAndConstantLoaderImpl
@@ -113,7 +113,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
property.setCompileTimeInitializer( property.setCompileTimeInitializer(
c.storageManager.createNullableLazyValue { c.storageManager.createNullableLazyValue {
val container = c.containingDeclaration.asProtoContainer() val container = c.containingDeclaration.asProtoContainer()
c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, c.nameResolver, AnnotatedCallableKind.PROPERTY) c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, c.nameResolver, property.getReturnType())
} }
) )
} }