Protobuf 文件语法

Protobuf 文件的具体语法


1. 基本语法

1.1 语法版本

使用 syntax 指定 Protobuf 的版本(proto2proto3),目前推荐使用 proto3

syntax = "proto3";

1.2 包声明

使用 package 定义命名空间,避免不同模块间的命名冲突。

package mypackage;

1.3 导入其他文件

可以通过 import 导入其他 .proto 文件中的定义。

import "common.proto";

2. 数据类型

2.1 标量类型

Protobuf 支持多种标量类型:

数据类型 说明 示例
int32 / int64 整数,32位或64位 int32 age = 1;
uint32 / uint64 无符号整数,32位或64位 uint32 id = 2;
float 单精度浮点数 float score = 3;
double 双精度浮点数 double ratio = 4;
bool 布尔值 bool is_active = 5;
string 字符串 string name = 6;
bytes 二进制数据 bytes data = 7;

2.2 复合类型

  • 枚举类型:用于定义一组命名常量。
  • 消息类型:类似于结构体,用于定义复杂的数据结构。

3. 消息定义

3.1 基本结构

消息是 Protobuf 的核心,用于定义数据结构。

message User {
    int32 id = 1;       // 用户ID
    string name = 2;    // 用户名
    bool is_active = 3; // 是否活跃
}

3.2 可选字段

proto3 中,所有字段默认是可选的,无需显式标记。

3.3 嵌套消息

消息可以包含其他消息作为字段。

message Address {
    string street = 1;
    string city = 2;
}

message User {
    int32 id = 1;
    string name = 2;
    Address address = 3; // 嵌套消息
}

3.4 枚举类型

用于定义一组枚举值。

enum UserType {
    UNKNOWN = 0;
    ADMIN = 1;
    USER = 2;
}

message User {
    int32 id = 1;
    string name = 2;
    UserType type = 3;  // 使用枚举类型
}

3.5 重复字段

使用 repeated 定义列表字段。

message User {
    int32 id = 1;
    repeated string roles = 2; // 角色列表
}

4. 服务定义

4.1 服务结构

用于定义 RPC 服务的接口。

service UserService {
    rpc GetUser (UserRequest) returns (UserResponse);
    rpc ListUsers (Empty) returns (stream User);
}

4. 字段编号

每个字段需要分配一个唯一的编号,用于二进制编码时的标识。

message User {
    int32 id = 1;       // 字段编号从1开始
    string name = 2;    // 每个字段编号必须唯一
}
  • 字段编号的范围为 1 ~ 2^29 - 1。
  • 编号范围:
    • 1~15:适合频繁出现的小字段(编码紧凑)。
    • 16~2^29 - 1:一般字段。


---

### **5. 注释**

- 使用 `//` 添加单行注释。
- 使用 `/* */` 添加多行注释。

```proto
message User {
    int32 id = 1; // 用户ID
    /* 用户名 */
    string name = 2;
}

8. Protobuf 文件示例

完整示例:

syntax = "proto3";

package example;

import "google/protobuf/empty.proto";

enum UserType {
    UNKNOWN = 0;
    ADMIN = 1;
    USER = 2;
}

message User {
    int32 id = 1;
    string name = 2;
    UserType type = 3;
    repeated string roles = 4; // 用户角色
}

message UserRequest {
    int32 id = 1;
}

message UserResponse {
    User user = 1;
}

service UserService {
    rpc GetUser (UserRequest) returns (UserResponse);
    rpc ListUsers (google.protobuf.Empty) returns (stream User);
}

总结

  • Protobuf 文件.proto 为扩展名,定义了数据结构和 RPC 服务接口。
  • 通过 protoc 工具,可以根据 .proto 文件生成多种语言的代码。
  • 语法简单,支持多种类型和扩展性,适合分布式系统和微服务开发场景。
posted @ 2024-12-25 12:42  牛马chen  阅读(20)  评论(0编辑  收藏  举报