Add getExtensionOrNull utility for protobuf messages

This commit is contained in:
Alexander Udalov
2018-02-07 15:31:21 +01:00
parent 65a6171782
commit 7123202670
11 changed files with 51 additions and 55 deletions
@@ -311,9 +311,7 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
field: Boolean = false,
synthetic: Boolean = false
): MemberSignature? {
val signature =
if (proto.hasExtension(propertySignature)) proto.getExtension(propertySignature)
else return null
val signature = proto.getExtensionOrNull(propertySignature) ?: return null
if (field) {
val (name, desc) = JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable) ?: return null
@@ -339,8 +337,8 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
proto is ProtoBuf.Function -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null)
}
proto is ProtoBuf.Property && proto.hasExtension(propertySignature) -> {
val signature = proto.getExtension(propertySignature)
proto is ProtoBuf.Property -> {
val signature = proto.getExtensionOrNull(propertySignature) ?: return null
when (kind) {
AnnotatedCallableKind.PROPERTY_GETTER -> MemberSignature.fromMethod(nameResolver, signature.getter)
AnnotatedCallableKind.PROPERTY_SETTER -> MemberSignature.fromMethod(nameResolver, signature.setter)
@@ -63,8 +63,7 @@ object JvmProtoBufUtil {
nameResolver: NameResolver,
typeTable: TypeTable
): String? {
val signature =
if (proto.hasExtension(JvmProtoBuf.methodSignature)) proto.getExtension(JvmProtoBuf.methodSignature) else null
val signature = proto.getExtensionOrNull(JvmProtoBuf.methodSignature)
val name = if (signature != null && signature.hasName()) signature.name else proto.name
val desc = if (signature != null && signature.hasDesc()) {
nameResolver.getString(signature.desc)
@@ -85,8 +84,7 @@ object JvmProtoBufUtil {
nameResolver: NameResolver,
typeTable: TypeTable
): String? {
val signature =
if (proto.hasExtension(JvmProtoBuf.constructorSignature)) proto.getExtension(JvmProtoBuf.constructorSignature) else null
val signature = proto.getExtensionOrNull(JvmProtoBuf.constructorSignature)
val desc = if (signature != null && signature.hasDesc()) {
nameResolver.getString(signature.desc)
}
@@ -103,8 +101,7 @@ object JvmProtoBufUtil {
nameResolver: NameResolver,
typeTable: TypeTable
): PropertySignature? {
val signature =
if (proto.hasExtension(JvmProtoBuf.propertySignature)) proto.getExtension(JvmProtoBuf.propertySignature) else return null
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
val field =
if (signature.hasField()) signature.field else null
@@ -90,8 +90,7 @@ class AnnotationAndConstantLoaderImpl(
proto: ProtoBuf.Property,
expectedType: KotlinType
): ConstantValue<*>? {
if (!proto.hasExtension(protocol.compileTimeValue)) return null
val value = proto.getExtension(protocol.compileTimeValue)
val value = proto.getExtensionOrNull(protocol.compileTimeValue) ?: return null
return deserializer.resolveValue(expectedType, value, container.nameResolver)
}
}
@@ -0,0 +1,12 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
fun <M : GeneratedMessageLite.ExtendableMessage<M>, T> GeneratedMessageLite.ExtendableMessage<M>.getExtensionOrNull(
extension: GeneratedMessageLite.GeneratedExtension<M, T>
): T? = if (hasExtension(extension)) getExtension(extension) else null
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.getExtensionOrNull
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
import java.lang.reflect.Constructor
@@ -120,10 +121,8 @@ internal sealed class JvmPropertySignature {
val containingDeclaration = descriptor.containingDeclaration
if (descriptor.visibility == Visibilities.INTERNAL && containingDeclaration is DeserializedClassDescriptor) {
val classProto = containingDeclaration.classProto
val moduleName =
if (classProto.hasExtension(JvmProtoBuf.classModuleName))
nameResolver.getString(classProto.getExtension(JvmProtoBuf.classModuleName))
else JvmAbi.DEFAULT_MODULE_NAME
val moduleName = classProto.getExtensionOrNull(JvmProtoBuf.classModuleName)?.let(nameResolver::getString)
?: JvmAbi.DEFAULT_MODULE_NAME
return "$" + NameUtils.sanitizeAsJavaIdentifier(moduleName)
}
if (descriptor.visibility == Visibilities.PRIVATE && containingDeclaration is PackageFragmentDescriptor) {
@@ -210,14 +209,12 @@ internal object RuntimeTypeMapper {
return when (property) {
is DeserializedPropertyDescriptor -> {
val proto = property.proto
if (!proto.hasExtension(JvmProtoBuf.propertySignature)) {
// If this property has no JVM signature, it must be from built-ins
throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " +
"No metadata found for $property")
}
JvmPropertySignature.KotlinProperty(
property, proto, proto.getExtension(JvmProtoBuf.propertySignature), property.nameResolver, property.typeTable
)
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature)
?: // If this property has no JVM signature, it must be from built-ins
throw KotlinReflectionInternalError(
"Reflection on built-in Kotlin types is not yet fully supported. No metadata found for $property"
)
JvmPropertySignature.KotlinProperty(property, proto, signature, property.nameResolver, property.typeTable)
}
is JavaPropertyDescriptor -> {
val element = (property.source as? JavaSourceElement)?.javaElement
@@ -28,10 +28,7 @@ import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.VersionRequirementTable
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
@@ -139,9 +136,7 @@ internal val ReflectKotlinClass.packageModuleName: String?
val (nameResolver, proto) = JvmProtoBufUtil.readPackageDataFrom(header.data!!, header.strings!!)
// If no packageModuleName extension is written, the name is assumed to be JvmAbi.DEFAULT_MODULE_NAME
// (see JvmSerializerExtension.serializePackage)
if (proto.hasExtension(JvmProtoBuf.packageModuleName))
nameResolver.getString(proto.getExtension(JvmProtoBuf.packageModuleName))
else JvmAbi.DEFAULT_MODULE_NAME
proto.getExtensionOrNull(JvmProtoBuf.packageModuleName)?.let(nameResolver::getString) ?: JvmAbi.DEFAULT_MODULE_NAME
}
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
val partName = header.multifilePartNames.firstOrNull() ?: return null