Union(联合体)
XML union 使用指南。
Union 定义
例如,common.proto 中预定义的 union 类型 Target:
// Predefined union type.
message Target {
option (tableau.union) = {name:"Target"};
Type type = 9999 [(tableau.field) = { name: "Type" }];
oneof value {
option (tableau.oneof) = {
field: "Field"
};
Pvp pvp = 1; // Binded to enum value 1: TYPE_PVP.
Pve pve = 2; // Binded to enum value 2: TYPE_PVP.
Story story = 3; // Binded to enum value 3: TYPE_STORY.
Skill skill = 4; // Binded to enum value 4: TYPE_SKILL.
}
enum Type {
TYPE_NIL = 0;
TYPE_PVP = 1 [(tableau.evalue) = { name: "PVP" }];
TYPE_PVE = 2 [(tableau.evalue) = { name: "PVE" }];
TYPE_STORY = 3 [(tableau.evalue) = { name: "Story" }];
TYPE_SKILL = 4 [(tableau.evalue) = { name: "Skill" }];
}
message Pvp {
int32 type = 1; // scalar
int64 damage = 2; // scalar
repeated protoconf.FruitType types = 3; // incell enum list
}
message Pve {
Mission mission = 1; // incell struct
repeated int32 heros = 2; // incell list
map<int32, int64> dungeons = 3; // incell map
message Mission {
int32 id = 1;
uint32 level = 2;
int64 damage = 3;
}
}
message Story {
protoconf.Item cost = 1; // incell predefined struct
map<int32, protoconf.FruitType> fruits = 2; // incell map with value as enum type
map<int32, Flavor> flavors = 3; // incell map with key as enum type
message Flavor {
protoconf.FruitFlavor key = 1 [(tableau.field) = { name: "Key" }];
int32 value = 2 [(tableau.field) = { name: "Value" }];
}
}
message Skill {
int32 id = 1; // scalar
int64 damage = 2; // scalar
// no field tag 3
}
}
Predefined union
HelloWorld.xml 中的 worksheet ItemConf:
<?xml version="1.0" encoding="UTF-8"?>
<!--
<@TABLEAU>
<Item Sheet="ItemConf" />
</@TABLEAU>
<ItemConf>
<Target @type="{.Target}" />
</ItemConf>
-->
<ItemConf>
<Target Type="PVP" Field1="1" Field2="10" Field3="Apple,Orange,Banana"/>
</ItemConf>
生成结果:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xml"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf"};
protoconf.Target target = 1 [(tableau.field) = {name:"Target"}];
}
ItemConf.json
{
"target": {
"type": "TYPE_PVP",
"pvp": {
"type": 1,
"damage": "10",
"types": ["FRUIT_TYPE_APPLE", "FRUIT_TYPE_ORANGE", "FRUIT_TYPE_BANANA"]
}
}
}
Predefined incell union
HelloWorld.xml 中的 worksheet ItemConf:
<?xml version="1.0" encoding="UTF-8"?>
<!--
<@TABLEAU>
<Item Sheet="ItemConf" />
</@TABLEAU>
<ItemConf>
<Target>{.Target}|{form:FORM_TEXT}</Target>
</ItemConf>
-->
<ItemConf>
<Target>type:TYPE_PVE pve:{mission:{id:1 level:100 damage:999} heros:1 heros:2 heros:3 dungeons:{key:1 value:10} dungeons:{key:2 value:20} dungeons:{key:3 value:30}}</Target>
</ItemConf>
生成结果:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xml"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf"};
protoconf.Target target = 1 [(tableau.field) = {name:"Target" span:SPAN_INNER_CELL prop:{form:FORM_TEXT}}];
}
ItemConf.json
{
"target": {
"type": "TYPE_PVE",
"pve": {
"mission": {"id": 1, "level": 100, "damage": "999"},
"heros": [1, 2, 3],
"dungeons": {"1": "10", "2": "20", "3": "30"}
}
}
}
Predefined union list
HelloWorld.xml 中的 worksheet ItemConf:
<?xml version="1.0" encoding="UTF-8"?>
<!--
<@TABLEAU>
<Item Sheet="ItemConf" />
</@TABLEAU>
<ItemConf>
<Target @type="[.Target]" />
</ItemConf>
-->
<ItemConf>
<Target Type="Story" Field1="1001,10" Field2="1:Apple,2:Orange" Field3="Fragrant:1,Sour:2"/>
<Target Type="Skill" Field1="1" Field2="2"/>
</ItemConf>
生成结果:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xml"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf"};
repeated protoconf.Target target_list = 1 [(tableau.field) = {name:"Target"}];
}
ItemConf.json
{
"targetList": [
{
"type": "TYPE_STORY",
"story": {
"cost": {"id": 1001, "num": 10},
"fruits": {"1": "FRUIT_TYPE_APPLE", "2": "FRUIT_TYPE_ORANGE"},
"flavors": {
"1": {"key": "FRUIT_FLAVOR_FRAGRANT", "value": 1},
"2": {"key": "FRUIT_FLAVOR_SOUR", "value": 2}
}
}
},
{
"type": "TYPE_SKILL",
"skill": {"id": 1, "damage": "2"}
}
]
}