13af6ab5fSopenharmony_ci# How To Write Proto For Assembly 23af6ab5fSopenharmony_ci 33af6ab5fSopenharmony_ci## 消息格式 43af6ab5fSopenharmony_ci 53af6ab5fSopenharmony_ci``` 63af6ab5fSopenharmony_cisyntax = "proto3" // 指定版本信息 73af6ab5fSopenharmony_cimessage Test // message为关键字,作用为定义一种消息类型 83af6ab5fSopenharmony_ci{ 93af6ab5fSopenharmony_ci string test = 1; 103af6ab5fSopenharmony_ci} 113af6ab5fSopenharmony_ci``` 123af6ab5fSopenharmony_ci 133af6ab5fSopenharmony_ci消息由字段组合而成 143af6ab5fSopenharmony_ci``` 153af6ab5fSopenharmony_ci限定修饰符 数据类型 字段名称 = 唯一编号标签值 163af6ab5fSopenharmony_ci``` 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci## 限定修饰符说明 193af6ab5fSopenharmony_ci 203af6ab5fSopenharmony_ci### required 213af6ab5fSopenharmony_ci 223af6ab5fSopenharmony_cirequired 在发送消息之前必须设置该字段的值。对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。 233af6ab5fSopenharmony_ci 243af6ab5fSopenharmony_ci``` 253af6ab5fSopenharmony_cisyntax = "proto3" 263af6ab5fSopenharmony_cimessage Test 273af6ab5fSopenharmony_ci{ 283af6ab5fSopenharmony_ci required string test = 1; 293af6ab5fSopenharmony_ci} 303af6ab5fSopenharmony_ci``` 313af6ab5fSopenharmony_ci 323af6ab5fSopenharmony_ci### repeated 333af6ab5fSopenharmony_ci 343af6ab5fSopenharmony_cirepeated 代表可重复,我们可以理解为数组 353af6ab5fSopenharmony_ci 363af6ab5fSopenharmony_ci``` 373af6ab5fSopenharmony_cisyntax = "proto3" 383af6ab5fSopenharmony_cimessage Test 393af6ab5fSopenharmony_ci{ 403af6ab5fSopenharmony_ci string test = 1; 413af6ab5fSopenharmony_ci} 423af6ab5fSopenharmony_ci 433af6ab5fSopenharmony_cimessage TestArr 443af6ab5fSopenharmony_ci{ 453af6ab5fSopenharmony_ci repeated Test arr = 1; 463af6ab5fSopenharmony_ci} 473af6ab5fSopenharmony_ci``` 483af6ab5fSopenharmony_ci 493af6ab5fSopenharmony_ci### optional 503af6ab5fSopenharmony_ci 513af6ab5fSopenharmony_cioptional 表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。如果无法识别,则忽略该字段,消息中的其它字段正常处理。 523af6ab5fSopenharmony_ci 533af6ab5fSopenharmony_ci## 数据类型 543af6ab5fSopenharmony_ci 553af6ab5fSopenharmony_ci| proto类型 | C++类型 | 备注 | 563af6ab5fSopenharmony_ci|:-----------|:---------------|:------------| 573af6ab5fSopenharmony_ci|double |double | 64位浮点数 583af6ab5fSopenharmony_ci|float |float | 32位浮点数 593af6ab5fSopenharmony_ci|int32 |int32 | 32位整数 603af6ab5fSopenharmony_ci|int64 |int64 | 64位整数 613af6ab5fSopenharmony_ci|uint32 |uint32 | 32位无符号整数 623af6ab5fSopenharmony_ci|uint64 |uint64 | 64位无符号整数 633af6ab5fSopenharmony_ci|sint32 |int32 | 32位整数,处理负数效率比int32更高 643af6ab5fSopenharmony_ci|sint32 |sint64 | 64位整数,处理负数效率比int64更高 653af6ab5fSopenharmony_ci|fixed32 | uint32 | 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。 663af6ab5fSopenharmony_ci|fixed64 | uint64 | 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。 673af6ab5fSopenharmony_ci|sfixed32 | int32 | 总是4个字节 683af6ab5fSopenharmony_ci|sfixed64 | int64 | 总是8个字节 693af6ab5fSopenharmony_ci|bool | bool | 布尔类型 703af6ab5fSopenharmony_ci|string | string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本 713af6ab5fSopenharmony_ci|bytes | string | 处理多字节的语言字符、如中文 723af6ab5fSopenharmony_ci|enum | enum | 枚举(proto2 从1开始,proto3从0开始) 733af6ab5fSopenharmony_ci|message | object of class | 自定义的消息类型 743af6ab5fSopenharmony_ci 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_ci## 字段名称 773af6ab5fSopenharmony_ci 783af6ab5fSopenharmony_ciprotobuf建议以下划线命名而非驼峰式 793af6ab5fSopenharmony_ci 803af6ab5fSopenharmony_ci## 唯一的编号标签 813af6ab5fSopenharmony_ci 823af6ab5fSopenharmony_ci代表每个字段的一个唯一的编号标签,在同一个消息里不可以重复。这些编号标签用与在消息二进制格式中标识你的字段,并且消息一旦定义就不能更改。需要说明的是标签在1到15范围的采用一个字节进行编码,所以通常将标签1到15用于频繁发生的消息字段。编号标签大小的范围是1到229。此外不能使用protobuf系统预留的编号标签(19000 ~19999) 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_ci## import 853af6ab5fSopenharmony_ci 863af6ab5fSopenharmony_ciprotobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。 873af6ab5fSopenharmony_ci 883af6ab5fSopenharmony_ci## enum 893af6ab5fSopenharmony_ci 903af6ab5fSopenharmony_ci``` 913af6ab5fSopenharmony_cisyntax = "proto3" // 指定版本信息 923af6ab5fSopenharmony_cienum COLOR 933af6ab5fSopenharmony_ci{ 943af6ab5fSopenharmony_ci RED = 0; 953af6ab5fSopenharmony_ci BLUE = 1; 963af6ab5fSopenharmony_ci YELLOW = 2; 973af6ab5fSopenharmony_ci} 983af6ab5fSopenharmony_ci 993af6ab5fSopenharmony_cimessage Test // message为关键字,作用为定义一种消息类型 1003af6ab5fSopenharmony_ci{ 1013af6ab5fSopenharmony_ci string test = 1; 1023af6ab5fSopenharmony_ci COLOR type = 2; 1033af6ab5fSopenharmony_ci} 1043af6ab5fSopenharmony_ci``` 1053af6ab5fSopenharmony_ci 1063af6ab5fSopenharmony_ci## package 1073af6ab5fSopenharmony_ci 1083af6ab5fSopenharmony_ci``` 1093af6ab5fSopenharmony_cisyntax = "proto3" // 指定版本信息 1103af6ab5fSopenharmony_ci 1113af6ab5fSopenharmony_cipackage tutorial; 1123af6ab5fSopenharmony_ci 1133af6ab5fSopenharmony_cimessage Test // message为关键字,作用为定义一种消息类型 1143af6ab5fSopenharmony_ci{ 1153af6ab5fSopenharmony_ci string test = 1; 1163af6ab5fSopenharmony_ci} 1173af6ab5fSopenharmony_ci``` 1183af6ab5fSopenharmony_ci 1193af6ab5fSopenharmony_ci## oneof 1203af6ab5fSopenharmony_ci 1213af6ab5fSopenharmony_cimessage 包含许多可选字段,并且最多只能同时设置其中一个字段,则可以使用 oneof 功能强制执行此行为并节省内存 1223af6ab5fSopenharmony_ci 1233af6ab5fSopenharmony_ci# Assembly对应Proto 1243af6ab5fSopenharmony_ci 1253af6ab5fSopenharmony_ci## class\struct 1263af6ab5fSopenharmony_ci 1273af6ab5fSopenharmony_ciprotobuf中将类型信息结构化处理,通过自定义消息message结构对C++中class或struct进行解析处理 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ciC++ 1303af6ab5fSopenharmony_ci``` 1313af6ab5fSopenharmony_cistruct Ins { 1323af6ab5fSopenharmony_ci size_t line_number = 0; 1333af6ab5fSopenharmony_ci uint32_t column_number = 0; 1343af6ab5fSopenharmony_ci std::string whole_line = ""; 1353af6ab5fSopenharmony_ci size_t bound_left = 0; 1363af6ab5fSopenharmony_ci size_t bound_right = 0; 1373af6ab5fSopenharmony_ci} 1383af6ab5fSopenharmony_ci``` 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ciproto 1413af6ab5fSopenharmony_ci``` 1423af6ab5fSopenharmony_cimessage DebuginfoIns { 1433af6ab5fSopenharmony_ci uint64 lineNumber = 1; 1443af6ab5fSopenharmony_ci uint32 columnNumber = 2; 1453af6ab5fSopenharmony_ci bytes wholeLine = 3; 1463af6ab5fSopenharmony_ci uint64 boundLeft = 4; 1473af6ab5fSopenharmony_ci uint64 boundRight = 5; 1483af6ab5fSopenharmony_ci} 1493af6ab5fSopenharmony_ci``` 1503af6ab5fSopenharmony_ci 1513af6ab5fSopenharmony_ci 1523af6ab5fSopenharmony_ci## enum 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ciprotobuf中存在enum类型,proto2 从1开始,proto3从0开始 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_ci对于Assembly中的转换,优化序列化速度,通过uint32位直接进行转换: 1573af6ab5fSopenharmony_ci 1583af6ab5fSopenharmony_ciC++ 1593af6ab5fSopenharmony_ci``` 1603af6ab5fSopenharmony_ciclass Value { 1613af6ab5fSopenharmony_cipublic: 1623af6ab5fSopenharmony_ci enum class Type { 1633af6ab5fSopenharmony_ci U1, 1643af6ab5fSopenharmony_ci I8, 1653af6ab5fSopenharmony_ci U8, 1663af6ab5fSopenharmony_ci I16, 1673af6ab5fSopenharmony_ci U16, 1683af6ab5fSopenharmony_ci I32, 1693af6ab5fSopenharmony_ci U32, 1703af6ab5fSopenharmony_ci I64, 1713af6ab5fSopenharmony_ci U64, 1723af6ab5fSopenharmony_ci F32, 1733af6ab5fSopenharmony_ci F64, 1743af6ab5fSopenharmony_ci STRING, 1753af6ab5fSopenharmony_ci STRING_NULLPTR, 1763af6ab5fSopenharmony_ci RECORD, 1773af6ab5fSopenharmony_ci METHOD, 1783af6ab5fSopenharmony_ci ENUM, 1793af6ab5fSopenharmony_ci ANNOTATION, 1803af6ab5fSopenharmony_ci ARRAY, 1813af6ab5fSopenharmony_ci VOID, 1823af6ab5fSopenharmony_ci METHOD_HANDLE, 1833af6ab5fSopenharmony_ci UNKNOWN 1843af6ab5fSopenharmony_ci }; 1853af6ab5fSopenharmony_ci ... 1863af6ab5fSopenharmony_ci} 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci``` 1893af6ab5fSopenharmony_ci 1903af6ab5fSopenharmony_ci 1913af6ab5fSopenharmony_ciproto 1923af6ab5fSopenharmony_ci``` 1933af6ab5fSopenharmony_cimessage Value { 1943af6ab5fSopenharmony_ci uint32 type = 1; 1953af6ab5fSopenharmony_ci} 1963af6ab5fSopenharmony_ci``` 1973af6ab5fSopenharmony_ci## inheritance 1983af6ab5fSopenharmony_ci 1993af6ab5fSopenharmony_ciprotobuf中message无继承信息,开发者自己实现继承信息 2003af6ab5fSopenharmony_ci 2013af6ab5fSopenharmony_ciC++ 2023af6ab5fSopenharmony_ci``` 2033af6ab5fSopenharmony_ciclass Value { 2043af6ab5fSopenharmony_ci... 2053af6ab5fSopenharmony_ci} 2063af6ab5fSopenharmony_ci 2073af6ab5fSopenharmony_ciclass ArrayValue : public Value { 2083af6ab5fSopenharmony_ci... 2093af6ab5fSopenharmony_ci} 2103af6ab5fSopenharmony_ci``` 2113af6ab5fSopenharmony_ci 2123af6ab5fSopenharmony_ciproto 2133af6ab5fSopenharmony_ci``` 2143af6ab5fSopenharmony_ci 2153af6ab5fSopenharmony_cimessage Value { 2163af6ab5fSopenharmony_ci uint32 type = 1; 2173af6ab5fSopenharmony_ci} 2183af6ab5fSopenharmony_ci 2193af6ab5fSopenharmony_cimessage ArrayValue { 2203af6ab5fSopenharmony_ci Value father = 1; 2213af6ab5fSopenharmony_ci} 2223af6ab5fSopenharmony_ci 2233af6ab5fSopenharmony_ci``` 2243af6ab5fSopenharmony_ci 2253af6ab5fSopenharmony_ci## std::variant 2263af6ab5fSopenharmony_ci 2273af6ab5fSopenharmony_ci通过oneof关键字实现std::variant 2283af6ab5fSopenharmony_ci 2293af6ab5fSopenharmony_ciC++ 2303af6ab5fSopenharmony_ci``` 2313af6ab5fSopenharmony_cistd::variant<uint64_t, float, double, std::string, pandasm::Type, AnnotationData> value_; 2323af6ab5fSopenharmony_ci``` 2333af6ab5fSopenharmony_ci 2343af6ab5fSopenharmony_ciproto 2353af6ab5fSopenharmony_ci``` 2363af6ab5fSopenharmony_cioneof value { 2373af6ab5fSopenharmony_ci uint64 valueU64 = 2; 2383af6ab5fSopenharmony_ci float valueFloat = 3; 2393af6ab5fSopenharmony_ci double valueDouble = 4; 2403af6ab5fSopenharmony_ci bytes valueStr = 5; 2413af6ab5fSopenharmony_ci Type valueType = 6; 2423af6ab5fSopenharmony_ci AnnotationData valueAnno = 7; 2433af6ab5fSopenharmony_ci} 2443af6ab5fSopenharmony_ci``` 2453af6ab5fSopenharmony_ci 2463af6ab5fSopenharmony_ci## unique_ptr 2473af6ab5fSopenharmony_ci 2483af6ab5fSopenharmony_ci查看源码中的变量关系,通过oneof实现智能指针 2493af6ab5fSopenharmony_ci 2503af6ab5fSopenharmony_ciC++ 2513af6ab5fSopenharmony_ci``` 2523af6ab5fSopenharmony_ciclass Value { 2533af6ab5fSopenharmony_ci} 2543af6ab5fSopenharmony_ci 2553af6ab5fSopenharmony_ciclass ArrayValue { 2563af6ab5fSopenharmony_ci} 2573af6ab5fSopenharmony_ci 2583af6ab5fSopenharmony_ciclass ScalarValue { 2593af6ab5fSopenharmony_ci} 2603af6ab5fSopenharmony_ci 2613af6ab5fSopenharmony_cistd::unique_ptr<Value> value_; 2623af6ab5fSopenharmony_ci``` 2633af6ab5fSopenharmony_ci 2643af6ab5fSopenharmony_ciproto 2653af6ab5fSopenharmony_ci``` 2663af6ab5fSopenharmony_cimessage Value { 2673af6ab5fSopenharmony_ci} 2683af6ab5fSopenharmony_ci 2693af6ab5fSopenharmony_cimessage ScalarValue { 2703af6ab5fSopenharmony_ci Value father = 1; 2713af6ab5fSopenharmony_ci} 2723af6ab5fSopenharmony_ci 2733af6ab5fSopenharmony_cimessage ArrayValue { 2743af6ab5fSopenharmony_ci Value father = 1; 2753af6ab5fSopenharmony_ci} 2763af6ab5fSopenharmony_ci 2773af6ab5fSopenharmony_cioneof value { 2783af6ab5fSopenharmony_ci ScalarValue scalar = 2; 2793af6ab5fSopenharmony_ci ArrayValue array = 3; 2803af6ab5fSopenharmony_ci} 2813af6ab5fSopenharmony_ci``` 282