我有以下 protobuf 设置:
import "google/protobuf/any.proto";
message EntityEnvelope {
string id = 1;
string entity_type = 2;
google.protobuf.Any entity = 3;
}
message EntityABC {
string name = 1;
}
message EntityXYZ {
string desc = 1;
}
whereEntityEnvelope.entity
可以是任何类型打包为google.protobuf.Any
. 每个 protobuf 消息都存储在编码为 Base64 的磁盘中。
阅读这些消息时,如果我在解包时在编译类型中使用特定的实体类型,它会完美运行:
import scalapb.spark.Implicits._
spark.read.format("text")
.load("/tmp/entity").as[String]
.map { s => Base64.getDecoder.decode(s) }
.map { bytes => EntityEnvelope.parseFrom(bytes) }
.map { envelope => envelope.getEntity.unpack[EntityXYZ]}
.show()
但我想使用相同的代码在运行时读取任何类型的实体,而无需指定其类型。我得到的“更接近”是(但甚至没有编译):
val entityClass = Class.forName(qualifiedEntityClassNameFromRuntime)
spark.read.format("text")
.load("/tmp/entity").as[String]
.map { s => Base64.getDecoder.decode(s) }
.map { bytes => EntityEnvelope.parseFrom(bytes) }
.map { envelope => toJavaProto(envelope.getEntity).unpack(entityClass)} // ERROR: No implicits found for Encoder[Any]
.show()
由于Any
包含typeUrl
, 是否可以找到正确的描述符并在运行时自动解包,而无需在编译时指定类型?