protobuf-lua-gen 中使用 bytes

发表于2017-11-24
评论0 2.9k浏览

protobuf - lua -gen 中的数据类型参考下图


bytes 我们就用string 来传值就可以。


比如下面的 Person.proto

message Person   
{  
  required int32 id = 1;  
  required bytes param = 2;  
}  

可以下如下使用
package.path = package.path .. ';../protobuf/?.lua;../protobuf/luascript/?.lua'  
package.cpath = package.cpath .. ';../protobuf/?.so'  
require 'Person_pb'  
local person= Person_pb.Person()  
person.id = 1000  
person.param=tostring(123)  
local data = person:SerializeToString()  
print(person)  


更多请查看 https://github.com/indygreg/lua-protobuf/wiki/Lua-API

Lua API

This page documents the API by which protocol buffers are used in Lua.

Protocol Buffer Support

The following table describes the level of support for protocol buffer message features:

DefinitionsSupport Level
Optional FieldsFull
Required FieldsFull
Repeated FieldsFull
Default ValuesFull
EnumerationsFull
Nested TypesFull
GroupsWon't Implement (deprecated)
ExtensionsPlanned
Nested ExtensionsTBD
ServicesPlanned
OptionsPlanned

The following table describes support for the scalar field types on messages:

TypeSupported?Lua Type
doubleYesnumber
floatYesnumber
int32Yesnumber
int64Not Robustnumber
uint32Yesnumber
uint64Not Robustnumber
sint32Yesnumber
sint64Not Robustnumber
fixed32Yesnumber
fixed64Not Robustnumber
sfixed32Yesnumber
sfixed64Not Robustnumber
boolYesboolean
stringYesstring
bytesYesstring

Message Types

Each protocol buffer message is registered as a Lua type. The type name is


"protobuf." + :package + "." + :message_name 

For example, the messages in the following protocol buffer definition:

package acme.example;
message msgA {
    optional string name = 1;
}
message lua {
    repeated uint32 value = 1;
} 

correspond to the Lua types:

protobuf.acme.example.msgA
protobuf.acme.example.lua 

Constructing Messages

From Lua, you can create protocol buffer messages by calling the new function of the Lua message type:

-- create an empty msgA message from the acme.example package
msg = protobuf.acme.example.msgA.new() 

This is equivalent to calling the C++ constructor with no arguments.

If you have a string containing the serialized content of a message, call the parsefromstring function of the Lua message type:

-- parse message from contents of a variable, serialized
msg = protobuf.acme.example.msgA.parsefromstring(serialized) 

Common Message Instance Functions

Each Lua message type has a handful of common functions:

-- message in variable 'msg'
-- obtain serialized value of message, as a string
serialized = msg:serialized()
-- clear all fields from message
msg:clear() 

Message Fields

Each message field defines a number of accessor and mutator methods.

The name of these functions is the form:

:action + "_" + :field 

All field labels (requiredoptionalrepeated) have the clearget, and set actions:

msg:clear_name()
value = msg:get_name()
msg:set_name("new value") 

For repeated fields, get and set add a required argument, which is the offset to get/set. By Lua convention, the first element is offset 1.

value1, value2 = msg:get_name(1), msg:get_name(2)
msg:set_name(1, "new value")
-- this will result in error b/c the offset is invalid
value = msg:get_name(0)
-- you will also get an error if you attempt to retrieve an offset that doesn't exist
-- assume msg:size_name() == 2
-- this will error:
msg:get_name(3) 

This function does not return any values.

required and optional fields have the has action:

bool = msg:has_name() 

repeated fields have the size action, which returns the number of elements:

size = msg:size_multiple() 

Embedded Messages

It is possible to embed one protocol buffer message inside another. This is supported in the Lua interface, but the API is slightly different from scalar values.

First, we mimic the C++ API where the )set_()_ function doesn't exist.

-- this clears a message
msg:set_embedded(nil)
-- this throws an error
msg:set_embedded(msg_instance) 

To modify embedded messages, you call the get()_ function and modify the returned object.

embedded = msg:get_embedded()
embedded:set_field(new_value)
-- change reflected in parent message automatically 

To add an embedded message to a repeated field:

embedded = msg:add_embedded()
-- do stuff with message 

Currently there is a bug dealing with treatment of the mutable pointers Lua is using under the hood. The following will likely crash your process:

embedded = msg:get_embedded()
msg:clear_embedded()
-- crash happens on next line
embedded:get_value() 

This will hopefully be fixed in a later version.


Table Access to Fields

Messages can also be treated as tables. Just set the message field name as the table key.

value = msg['name']
msg['name'] = 'new value' 

Repeated message fields are themselves tables. However, they are indexed by an integer value, starting from 1, as that is the Lua convention.

value = msg['value'][1] 

Table access is not yet available. The syntax is documented here for reference during implementation.


Enumerations

Enumerations are represented as Lua tables. Table keys are the strings which correspond to the enumerated values. Table values are the respective integer values of these keys.

Enumeration type names are assigned from the package, message, and enumeration name.

If the enumeration was defined at file/package scope (outside a message), the Lua type name will be:

:package + "." + :enum 

If the enumeration was defined inside a message, the Lua type name will be:

:package + "." + :message + "." + :enum 

Let's take the following .proto file as an example:

package acme;
enum Color {
    RED = 0;
    GREEN = 1;
    BLUE = 2;
}
message Car {
    optional Color color = 1;
}
message Sign {
    enum Shape {
        SQUARE = 1;
        ROUND = 2;
    }
    optional Shape shape = 1;
} 

Here is how you would interact with the enumerations:

car = protobuf.acme.Car.new()
car.set_color(protobuf.acme.Color['GREEN'])
color = car.get_color()
sign = protobuf.acme.Sign.new()
sign.set_shape(protobuf.acme.Sign.Shape['SQUARE']) 

Of course, the "." syntax in Lua is just a shortcut for table access, so if you really wanted:

value = protobuf['acme']['Color']['GREEN']

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论