1# How To Write Proto For Assembly 2 3## 消息格式 4 5``` 6syntax = "proto3" // 指定版本信息 7message Test // message为关键字,作用为定义一种消息类型 8{ 9 string test = 1; 10} 11``` 12 13消息由字段组合而成 14``` 15限定修饰符 数据类型 字段名称 = 唯一编号标签值 16``` 17 18## 限定修饰符说明 19 20### required 21 22required 在发送消息之前必须设置该字段的值。对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。 23 24``` 25syntax = "proto3" 26message Test 27{ 28 required string test = 1; 29} 30``` 31 32### repeated 33 34repeated 代表可重复,我们可以理解为数组 35 36``` 37syntax = "proto3" 38message Test 39{ 40 string test = 1; 41} 42 43message TestArr 44{ 45 repeated Test arr = 1; 46} 47``` 48 49### optional 50 51optional 表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。如果无法识别,则忽略该字段,消息中的其它字段正常处理。 52 53## 数据类型 54 55| proto类型 | C++类型 | 备注 | 56|:-----------|:---------------|:------------| 57|double |double | 64位浮点数 58|float |float | 32位浮点数 59|int32 |int32 | 32位整数 60|int64 |int64 | 64位整数 61|uint32 |uint32 | 32位无符号整数 62|uint64 |uint64 | 64位无符号整数 63|sint32 |int32 | 32位整数,处理负数效率比int32更高 64|sint32 |sint64 | 64位整数,处理负数效率比int64更高 65|fixed32 | uint32 | 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。 66|fixed64 | uint64 | 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。 67|sfixed32 | int32 | 总是4个字节 68|sfixed64 | int64 | 总是8个字节 69|bool | bool | 布尔类型 70|string | string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本 71|bytes | string | 处理多字节的语言字符、如中文 72|enum | enum | 枚举(proto2 从1开始,proto3从0开始) 73|message | object of class | 自定义的消息类型 74 75 76## 字段名称 77 78protobuf建议以下划线命名而非驼峰式 79 80## 唯一的编号标签 81 82代表每个字段的一个唯一的编号标签,在同一个消息里不可以重复。这些编号标签用与在消息二进制格式中标识你的字段,并且消息一旦定义就不能更改。需要说明的是标签在1到15范围的采用一个字节进行编码,所以通常将标签1到15用于频繁发生的消息字段。编号标签大小的范围是1到229。此外不能使用protobuf系统预留的编号标签(19000 ~19999) 83 84## import 85 86protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。 87 88## enum 89 90``` 91syntax = "proto3" // 指定版本信息 92enum COLOR 93{ 94 RED = 0; 95 BLUE = 1; 96 YELLOW = 2; 97} 98 99message Test // message为关键字,作用为定义一种消息类型 100{ 101 string test = 1; 102 COLOR type = 2; 103} 104``` 105 106## package 107 108``` 109syntax = "proto3" // 指定版本信息 110 111package tutorial; 112 113message Test // message为关键字,作用为定义一种消息类型 114{ 115 string test = 1; 116} 117``` 118 119## oneof 120 121message 包含许多可选字段,并且最多只能同时设置其中一个字段,则可以使用 oneof 功能强制执行此行为并节省内存 122 123# Assembly对应Proto 124 125## class\struct 126 127protobuf中将类型信息结构化处理,通过自定义消息message结构对C++中class或struct进行解析处理 128 129C++ 130``` 131struct Ins { 132 size_t line_number = 0; 133 uint32_t column_number = 0; 134 std::string whole_line = ""; // TODO(mbolshov): redundant given file and line_number 135 size_t bound_left = 0; 136 size_t bound_right = 0; 137} 138``` 139 140proto 141``` 142message DebuginfoIns { 143 uint64 lineNumber = 1; 144 uint32 columnNumber = 2; 145 bytes wholeLine = 3; 146 uint64 boundLeft = 4; 147 uint64 boundRight = 5; 148} 149``` 150 151 152## enum 153 154protobuf中存在enum类型,proto2 从1开始,proto3从0开始 155 156对于Assembly中的转换,优化序列化速度,通过uint32位直接进行转换: 157 158C++ 159``` 160class Value { 161public: 162 enum class Type { 163 U1, 164 I8, 165 U8, 166 I16, 167 U16, 168 I32, 169 U32, 170 I64, 171 U64, 172 F32, 173 F64, 174 STRING, 175 STRING_NULLPTR, 176 RECORD, 177 METHOD, 178 ENUM, 179 ANNOTATION, 180 ARRAY, 181 VOID, 182 METHOD_HANDLE, 183 UNKNOWN 184 }; 185 ... 186} 187 188``` 189 190 191proto 192``` 193message Value { 194 uint32 type = 1; 195} 196``` 197## inheritance 198 199protobuf中message无继承信息,开发者自己实现继承信息 200 201C++ 202``` 203class Value { 204... 205} 206 207class ArrayValue : public Value { 208... 209} 210``` 211 212proto 213``` 214 215message Value { 216 uint32 type = 1; 217} 218 219message ArrayValue { 220 Value father = 1; 221} 222 223``` 224 225## std::variant 226 227通过oneof关键字实现std::variant 228 229C++ 230``` 231std::variant<uint64_t, float, double, std::string, pandasm::Type, AnnotationData> value_; 232``` 233 234proto 235``` 236oneof value { 237 uint64 valueU64 = 2; 238 float valueFloat = 3; 239 double valueDouble = 4; 240 bytes valueStr = 5; 241 Type valueType = 6; 242 AnnotationData valueAnno = 7; 243} 244``` 245 246## unique_ptr 247 248查看源码中的变量关系,通过oneof实现智能指针 249 250C++ 251``` 252class Value { 253} 254 255class ArrayValue { 256} 257 258class ScalarValue { 259} 260 261std::unique_ptr<Value> value_; 262``` 263 264proto 265``` 266message Value { 267} 268 269message ScalarValue { 270 Value father = 1; 271} 272 273message ArrayValue { 274 Value father = 1; 275} 276 277oneof value { 278 ScalarValue scalar = 2; 279 ArrayValue array = 3; 280} 281``` 282