Union(联合体)

YAML 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;
    int64 damage = 2;
    repeated protoconf.FruitType types = 3;
  }
  message Pve {
    Mission mission = 1;
    repeated int32 heros = 2;
    map<int32, int64> dungeons = 3;

    message Mission {
      int32 id = 1;
      uint32 level = 2;
      int64 damage = 3;
    }
  }
  message Story {
    protoconf.Item cost = 1;
    map<int32, protoconf.FruitType> fruits = 2;
    map<int32, Flavor> flavors = 3;
    message Flavor {
      protoconf.FruitFlavor key = 1 [(tableau.field) = { name: "Key" }];
      int32 value = 2 [(tableau.field) = { name: "Value" }];
    }
  }
  message Skill {
    int32 id = 1;
    int64 damage = 2;
  }
}

Predefined union

HelloWorld.yaml 中的 worksheet ItemConf

# define metasheet: generate all sheets
"@sheet": "@TABLEAU"
---
# define schema
"@sheet": "@ItemConf"
Target: "{.Target}"
---
"@sheet": ItemConf
Target:
  Type: PVP
  Field1: 1
  Field2: 10
  Field3: "Apple,Orange,Banana"

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.yaml"};

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.yaml 中的 worksheet ItemConf

# define metasheet: generate all sheets
"@sheet": "@TABLEAU"
---
# define schema
"@sheet": "@ItemConf"
Target:
  "@type": "{.Target}|{form:FORM_TEXT}"
  "@incell": true
---
"@sheet": 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}}"

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.yaml"};

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.yaml 中的 worksheet ItemConf

# define metasheet: generate all sheets
"@sheet": "@TABLEAU"
---
# define schema
"@sheet": "@ItemConf"
Targets: "[.Target]"
---
"@sheet": ItemConf
Targets: 
  - Type: Story
    Field1: "1001,10"
    Field2: "1:Apple,2:Orange"
    Field3: "Fragrant:1,Sour:2"
  - Type: Skill
    Field1: 1
    Field2: 2

生成结果:

hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.yaml"};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated protoconf.Target targets = 1 [(tableau.field) = {name:"Targets"}];
}
ItemConf.json
{
    "targets": [
        {
            "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"}
        }
    ]
}