【问题标题】:How to extract field from protobuf message without schema如何在没有架构的情况下从 protobuf 消息中提取字段
【发布时间】:2021-07-10 01:08:24
【问题描述】:

根据this issueprotoreflect 包提供了用于访问 protobuf 消息的“未知字段”的 API,但如果没有任何现有架构,我看不到任何使用它的方法。基本上,我想执行“弱解码”,类似于 JSON 解组器在输出类型为 map[string]interface{} 时所做的事情。

the documentation 的示例如下所示:

err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)

其中b 是输入字节切片,m 是输出消息,需要以某种方式对其进行初始化,如您所见here。我在想dynamicpb 可以用于此目的,但如果没有现有的MessageDescriptor,它看起来是不可能的,这就是我卡住的地方......

【问题讨论】:

    标签: go reflection protocol-buffers unmarshalling proto


    【解决方案1】:

    我可以使用低级别的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
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 2017-04-11
      • 2012-03-27
      • 1970-01-01
      • 2021-10-17
      • 2021-08-15
      • 2017-06-02
      • 1970-01-01
      • 2015-10-01
      相关资源
      最近更新 更多