starwing / lua-protobuf

A Lua module to work with Google protobuf
MIT License
1.73k stars 387 forks source link

repeated 下标从1开始? #216

Closed wilsonloo closed 1 year ago

wilsonloo commented 2 years ago

从项目示例的Person、Phone例子:

-- load schema from text (just for demo, use protoc.new() in real world)
assert(protoc:load [[
   message Phone {
      optional string name        = 1;
      optional int64  phonenumber = 2;
   }
   message Person {
      optional string name     = 1;
      optional int32  age      = 2;
      optional string address  = 3;
      repeated Phone  contacts = 4;
   }
   ]])

-- lua table data
local data = {
    name = "ilse",
    age  = 18,
    contacts = {
        { name = "alice", phonenumber = 12312341234 },
        { name = "bob",   phonenumber = 45645674567 }
    }
}
local bytes = assert(pb.encode("Person", data))
print(pb.tohex(bytes))
local data = assert(pb.decode("Person", bytes))
Log.Debug("unpacked:", data)

效果是对person定义了两个手机号码,pack/unpack 都正常:

0A 04 69 6C 73 65 10 12 22 0D 0A 05 61 6C 69 63 65 10 F2 D5 FD EE 2D 22 0C 0A 03 62 6F 62 10 C7 F0 C6 85 AA 01
unpacked: table:+name ["ilse"]
+age [18]
+contacts+1+name ["alice"]
|        | +phonenumber [12312341234]
|        +2+name ["bob"]
|        | +phonenumber [45645674567]

当如下插入个下标为0的电话后:

local data = {
    name = "ilse",
    age  = 18,
    contacts = {
        --[0] = { name = "zero", phonenumber = 100000000000 },
        { name = "alice", phonenumber = 12312341234 },
        { name = "bob",   phonenumber = 45645674567 }
    }
}
data.contacts[0] = { name = "zero", phonenumber = 100000000000 }

local bytes = assert(pb.encode("Person", data))
print(pb.tohex(bytes))
local data = assert(pb.decode("Person", bytes))
Log.Debug("unpacked:", data)

还是得到到上图一样的效果:

22 0D 10 F2 D5 FD EE 2D 0A 05 61 6C 69 63 65 22 0C 10 C7 F0 C6 85 AA 01 0A 03 62 6F 62 10 12 0A 04 69 6C 73 65
unpacked: table:+contacts+1+name ["alice"]
|        | +phonenumber [12312341234]
|        +2+name ["bob"]
|        | +phonenumber [45645674567]
+name ["ilse"]
+age [18]

即name=“zero”的记录不见了,而且是在pb.encode() 时丢失的。 当然将contacts 改为map是没问题的, 不过我是想问一下是本项目pack.encode() 对repeated有约束下标必须从1开始吗?还是protobuf本身就有这么个约束?在pack.encode() 时发现下标有异常的,有无提供一些错误抛出或警告机制?

wilsonloo commented 2 years ago

这是一个question,怎么选择不了label定义为question的

starwing commented 1 year ago

这是Lua的限制:数组必须从1开始。而repeated将table当作数组使用,其他key会被忽略。