我可以使用低级别的protowire 包来实现这一点。这是一个完整的示例,我提取了两个 uint64 类型的字段(在原始模式中恰好被分配了 field numbers 4 和 5):
import "google.golang.org/protobuf/encoding/protowire"
func getData(src []byte) (creationTime, expiryTime uint64, err error) {
remaining := src
for len(remaining) > 0 {
fieldNum, wireType, n := protowire.ConsumeTag(remaining)
if n < 0 {
return 0, 0, fmt.Errorf("failed to consume tag: %w", protowire.ParseError(n))
}
remaining = remaining[n:]
switch fieldNum {
case 4: // Expiry time
if wireType != protowire.VarintType {
return 0, 0, fmt.Errorf("unexpected type for expiry time field: %d", wireType)
}
expiryTime, n = protowire.ConsumeVarint(remaining)
case 5: // Creation time
if wireType != protowire.VarintType {
return 0, 0, fmt.Errorf("unexpected type for creation time field: %d", wireType)
}
creationTime, n = protowire.ConsumeVarint(remaining)
default:
n = protowire.ConsumeFieldValue(fieldNum, wireType, remaining)
}
if n < 0 {
return 0, 0, fmt.Errorf("failed to consume value for field %d: %w", fieldNum, protowire.ParseError(n))
}
remaining = remaining[n:]
}
return
}