protobuf语法详解

article/2025/8/30 6:40:33

文章目录

  • 一、包(package)
  • 二、选项(option)
  • 三、消息类型(message)
    • 3.1、常规消息类型
      • 3.1.1、字段修饰符
      • 3.1.2、字段类型
        • 3.1.2.1、标量类型
        • 3.1.2.2、枚举类型
        • 3.1.2.3、Any类型
        • 3.1.2.4、oneof类型
        • 3.1.2.5、map类型
      • 3.1.3、默认值说明
      • 3.1.4、标识号
    • 3.2、多个消息类型
    • 3.3、嵌套消息类型
    • 3.4、更新消息类型
  • 四、RPC服务(service)
  • 五、其他
    • 5.1 导入proto文件(import)

一、包(package)

  为.proto文件添加package声明符,可以防止不同 .proto项目间消息类型的命名发生冲突

package foo.bar;
message Open { ... }
message Foo {...foo.bar.Open open = 1;...
}

protobuf包类型的解析和C++类似,都是由内而外进行解析。对于C++,产生的类会被包装在C++的命名空间中,如上例中的Open会被封装在 foo::bar空间中。

二、选项(option)

  option会影响特定环境下的处理方式,但是不会改变整个文件声明的含义

option optimize_for = CODE_SIZE;

在这里插入图片描述

三、消息类型(message)

  message用于定义结构数据,可以包含多种类型字段(field),每个字段声明以分号结尾。message经过protoc编译后会生成对应的class类,field则会生成对应的方法

syntax = "proto3"; // 表示使用的protobuf版本是proto3message SearchRequest {string query = 1;int32 page_number = 2;int32 result_per_page = 3;
}

3.1、常规消息类型

3.1.1、字段修饰符

  在proto3中,去掉了required和optional,对于原始数据类型字段不再提供 hasxxx()方法,只有单个字段或者重复字段:

  • 单个字段:表示字段可以出现0次或者1次。

  • repeated:表示字段可以重复任意次。

3.1.2、字段类型

3.1.2.1、标量类型

  protobuf标量数据类型与各平台的数据类型对应如下表:
在这里插入图片描述

3.1.2.2、枚举类型

  protobuf中的enum类型和C++中的枚举类型相似,表示字段取值的集合

message SearchRequest {string query = 1;int32 page_number = 2;int32 result_per_page = 3;enum Corpus {UNIVERSAL = 0;WEB = 1;IMAGES = 2;LOCAL = 3;NEWS = 4;PRODUCTS = 5;VIDEO = 6;}Corpus corpus = 4;
}

  枚举类型中第一个元素的值必须从0开始,而且proto3中删除了default标记,默认值为第一个元素

  当枚举类型是在某一个消息内部定义,但是希望在另一个消息中使用时,需要采用MessageType.EnumType的语法格式。

3.1.2.3、Any类型

  protobuf中的Any类型与C++中的泛型概念类似,可以定义为任意的类型。在序列化的时候可以通过PackFrom()方法将任意的数据类型打包为Any类型,反序列化的时候通过UnpackTo()把Any类型还原为原始类型。

// 要使用Any类型必须导入该proto文件
import "google/protobuf/any.proto";message ErrorStatus {string message = 1;repeated google.protobuf.Any details = 2;
}
// Storing an arbitrary message type in Any.
NetworkErrorDetails details = ...;
ErrorStatus status;
status.add_details()->PackFrom(details);// Reading an arbitrary message from Any.
ErrorStatus status = ...;
for (const Any& detail : status.details()) {if (detail.Is<NetworkErrorDetails>()) {NetworkErrorDetails network_error;detail.UnpackTo(&network_error);... processing network_error ...}
}

3.1.2.4、oneof类型

  protobuf中的oneof类似与C++中的联合体类型相似,所有的字段共享内存,最多只能同时设置一个字段,设置oneof的任何字段会自动清除所有其他字段,可以使用case()或WhichOneof()方法检查oneof中使用的是哪个字段

message SampleMessage {oneof test_oneof {string name = 4;SubMessage sub_message = 9;}
}

【oneof特性】:

  • 设置oneof会自动清除其它oneof字段的值:
SampleMessage message;
message.set_name("name");
CHECK(message.has_name());
message.mutable_sub_message();   // Will clear name field.
CHECK(!message.has_name());
  • oneof不能声明为repeated类型。
  • 注意不要出现内存崩溃问题:
SampleMessage message;
SubMessage* sub_message = message.mutable_sub_message();
message.set_name("name");      // Will delete sub_message
sub_message->set_...            // Crashes here
  • 可以在oneof内部添加和删除field,但是删除和添加oneof要小心

3.1.2.5、map类型

  protobuf中的map类似与STL中的关联型容器相似,map是key-value类型,key可以是int或者string,value可以是自定义message

map<key_type, value_type> map_field = N;// 与上述定义等价
message MapFieldEntry {key_type key = 1;value_type value = 2;
}
repeated MapFieldEntry map_field = N;

【map特性】:

  • map不能定义为repeated类型。

  • 当为.proto文件产生生成文本格式的时候,map会按照key 的顺序排序,数值化的key会按照数值排序。

  • 从序列化中解析时,如果有重复的key,只会使用第一个key。

3.1.3、默认值说明

  • string类型,默认值是空字符串。

  • bytes类型,默认值是空bytes。

  • bool类型,默认值是false。

  • 数字类型,默认值是0。

  • 枚举类型,默认值是第一个枚举值,即0。

  • repeated修饰的属性,默认值是空。

3.1.4、标识号

  在消息类型中,每一个字段都有一个唯一的标识符(Tag),不应该随意改动

  [1-15]内的标识号在编码时只占用一个字节,包含标识符和字段类型,[16-2047]之间的标识符占用2个字节建议为频繁出现的字段使用[1-15]间的标识符

  如果考虑到以后可能扩展元素,可以预留一些标识符或者字段。注意不能在一个reserved声明中混合使用字段名和标识符。

message Foo {reserved 2, 15, 9 to 11;reserved "foo", "bar";
}

  最小的标识符可以从1开始,最大到2^29 - 1,或536,870,911。不可以使用[19000-19999]之间的标识符, Protobuf协议实现中预留了这些标识符。在.proto文件中使用这些预留标识号,编译时就会报错。

3.2、多个消息类型

  一个.proto文件中可以定义多个消息类型

syntax = "proto3";// SearchRequest 搜索请求
message SearchRequest {string query = 1;           // 查询字符串int32  page_number = 2;     // 页码int32  result_per_page = 3; // 每页条数
}// SearchResponse 搜索响应
message SearchResponse {...
}

3.3、嵌套消息类型

  在protobuf中message之前可以嵌套使用

message SearchResponse {message Result {string url = 1;string title = 2;repeated string snippets = 3;}repeated Result results = 1;
}

  内部声明的消息message名称只可在内部直接使用,在外部使用需要添加父级message名称(Parent.Type):

message SomeOtherMessage {SearchResponse.Result result = 1;
}

  支持多层嵌套:

message Outer {                // Level 0message MiddleAA {         // Level 1message Inner {        // Level 2int64 ival = 1;bool  booly = 2;}}message MiddleBB {         // Level 1message Inner {        // Level 2int32 ival = 1;bool  booly = 2;}}
}

3.4、更新消息类型

  如果一个已有的消息类型已无法满足新的需求,比如需要添加一个额外的字段,但是同时旧版本写的代码仍然可用。在更新消息类型需要遵循以下规则:

  • 不要更改任何已有字段的标识号

  • int32、uint32、int64、uint64,和bool是全部兼容的,这意味着可以将这些类型中的一个转换为另外一个,而不会破坏向前、 向后的兼容性

  • sint32和sint64是互相兼容的,但是它们与其他整数类型不兼容。

  • string和bytes是兼容的,只要bytes是有效的UTF-8编码。

  • 嵌套消息与bytes是兼容的,只要bytes包含该消息的一个编码过的版本。

  • fixed32与sfixed32是兼容的,fixed64与sfixed64是兼容的。

四、RPC服务(service)

  如果想要将消息类型用在远程方法调用(RPC)系统中,可以在.proto文件中定义一个RPC服务接口

service UserService {//  包含方法名、方法参数和返回值,// 接收SearchRequest并返回一个SearchResponserpc GetUser(Request) returns (Response); 
}

gRPC在使用protobuf时非常有效,如果使用特殊的protobuf插件可以直接从.proto文件中产生相关的RPC代码。

五、其他

5.1 导入proto文件(import)

  如果希望在当前proto文件中引用其他的proto文件中的内容,可以使用import:

import "other_project/other_protos.proto";

参考:
https://developers.google.cn/protocol-buffers/docs/proto3#oneof
https://segmentfault.com/a/1190000007917576#item-1-10
https://www.jianshu.com/p/e06ba6249edc


http://chatgpt.dhexx.cn/article/nb87Yx0L.shtml

相关文章

ProtoBuf在中C++使用介绍

ProtoBuf 我们先来看看官方文档给出的定义和描述&#xff1a; protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法&#xff0c;它可用于&#xff08;数据&#xff09;通信协议、数据存储等。 Protocol Buffers 是一种灵活&#xff0c;高效&#xff0c;自…

linux 安装protobuf

从github&#xff1a;https://github.com/protocolbuffers/protobuf 下载源代码 1、根据protobuf GitHub的README.md安装protoBuf &#xff08;1&#xff09;安装依赖工具 sudo apt-get install autoconf automake libtool curl make g unzip&#xff08;2&#xff09;在prot…

protobuf-master :编译篇

protobuf的编译其实相对简单&#xff0c;这里搬一下protobuf的ReadMe就很清楚了~ 如果是平时接触开源项目无从下手的小伙伴&#xff0c;也建议从阅读ReadMe开始哦! This directory contains CMake files that can be used to build protobuf with MSVC on Windows. You can bui…

ProtoBuf编码原理

背景 Protobuf是我们在网络传输中经常会用到的协议&#xff0c;优点是版本间兼容性强&#xff0c;对数据序列化时的极致压缩使得Protobuf包体积比xml、json等格式要小很多&#xff0c;节约流量。对于pb协议的具体使用方法&#xff0c;其官网有比较详细的说明&#xff0c;本文不…

windows protobuf编译

protobuf编译 Protobuf下载地址&#xff1a;https://github.com/protocolbuffers/protobuf/releases 1、配置cmake: 2、点击生成&#xff0c;打开工程文件&#xff1a;略 3、编译protobuf: 4、安装完成展示&#xff1a; 测试&#xff1a; 1、创建在bin目录下创建build.bat…

【Protobuf】Protobuf协议

Protobuf协议 什么是Protobuf一、编写proto文件二、生成协议类三、编码解码3.1 编码方法3.2 解码方法 什么是Protobuf Protobuf是谷歌发布的一套协议格式&#xff0c;它规定了一系列编码和解码方法。 目前&#xff0c;网上已经有不少实现Protobuf编码解码的库&#xff0c;可以…

protobuf简介

文章目录 一、protobuf的定义二、protobuf的优缺点2.1、优点2.2、缺点 三、protobuf的使用流程3.1、protobuf在Linux下的安装过程3.2、定义proto文件3.3、protoc编译器3.4、调用接口进行序列化、反序列化 四、protobuf的应用场景五、protobuf与json和XML的对比 一、protobuf的定…

java中使用protobuf总结

基本没怎么接触过java编程&#xff0c;别的团队发过来一个用java编写的存储pb的文件&#xff0c;让拆分和解析&#xff0c;硬着头皮做一下&#xff0c;在此将步骤做个记录&#xff1a; 下载安装protobuf https://github.com/protocolbuffers/protobuf/tags?afterv3.6.1.2 编译…

protobuf 详解

protobuf简介 Protobuf是Protocol Buffers的简称&#xff0c;它是Google公司开发的一种数据描述语言&#xff0c;是一种轻便高效的结构化数据存储格式&#xff0c;可以用于结构化数据串行化&#xff0c;或者说序列化 。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议…

protobuf介绍和语法

目录 前言 语法 标识符 字段 字段类型 proto2和proto3区别 前言 Protobuf即Protocol Buffers&#xff0c;是Google公司开发的一种跨语言和平台的序列化数据结构的方式&#xff0c;是一个灵活的、高效的用于序列化数据的协议。 与XML和JSON格式相比&#xff0c;pr…

Protobuf:一种更小、更快、更高效的协议

C/CLinux服务器开发/后台架构师知识体系 Protobuf介绍 Protobuf (Protocol Buffers) 是谷歌开发的一款无关平台&#xff0c;无关语言&#xff0c;可扩展&#xff0c;轻量级高效的序列化结构的数据格式&#xff0c;用于将自定义数据结构序列化成字节流&#xff0c;和将字节流反…

win10商店打不开_win10应用商店闪退是咋回事呢

win10虽然具有闪电般的开机速度&#xff0c;并且还新增了很多功能。但比较是全新的操作系统&#xff0c;所以难免会存在一些故障&#xff0c;这里小编就给大家讲讲win10应用商店闪退打不开怎么解决。 方法一 1&#xff0c;首先&#xff0c;打开开始菜单&#xff0c;进入设置&am…

电脑安装Linux闪退,win10系统运行内置Linux系统闪退如何处理

我们在win10系统电脑的使用中&#xff0c;有小伙伴在Linux系统的使用中出现了问题&#xff0c; win10系统运行内置Linux系统闪退的情况出现了&#xff0c;这是什么原因导致的呢&#xff0c;我们在win10系统运行内置Linux系统闪退如何处理&#xff0c;今天小编就来跟大家分享一下…

Java版mc闪退_本文传授win10运行mc闪退的具体操作对策

我们在使用电脑的时候遇到了win10运行mc闪退问题确实比较难受&#xff0c;要是你的电脑技术没有达到一定的水平&#xff0c;可能就不能解决这个win10运行mc闪退的情况。我们应当如何处理这个问题呢&#xff1f;小编先给大伙说说简单的措施&#xff1a;1、确保电脑中安装了 .NET…

(2022.5.27)【Win10】Windows10重置后微软商店闪退打不开、图片闪退打不开、UWP应用闪退打不开——可能的解决方案

更新日志 20220609 增加注意事项 注意事项 经过多为网友的反馈&#xff0c;目前这个方法是无法直接解决微软商店打不开的问题。因此&#xff0c;基于我目前的了解&#xff08;6月9日&#xff09;&#xff0c;如果大家遇到这个问题&#xff0c;真的只能重新 U 盘安装系统了。…

win10内置计算机和天气闪退,win10系统中天气闪退怎么办?Win10天气应用闪退问题解决方法...

win10系统中天气闪退怎么办&#xff1f;最近有部分用户在安装了win10系统后发现自带的天气应用出现闪退的情况&#xff0c;点击天气应用&#xff0c;发现它启动了很久&#xff0c;然后就自动关闭了。之后再点击天气应用就闪退&#xff0c;打不开。而尝试打开别的应用却可以正常…

解决WIN10下应用商店不能用,闪退的情况

解决WIN10下应用商店不能用,闪退的情况 先说下我的情况,也是博主手贱,经常看PC上的某个文件或者程序不顺眼的话就会想办法把它干掉,为此重装过几次系统… 这一次是装了win10的周年更新后,烦人的cortana,onedrive等一些我不想要的APP又回来了,在暴力清理这些APP的时候,需要特殊…

win10java闪退怎么办_Win10应用打不开或闪退怎么办?解决方案在此

可能有一些用户升级Win10之后遇到了应用商店、应用打不开或闪退的问题&#xff0c;此时可尝试通过下面的一些方法来解决。 1、点击任务栏的搜索(Cortana小娜)图标&#xff0c;输入Powershell&#xff0c;在搜索结果中右键单击Powershell&#xff0c;选择“以管理员身份运行”。…

win10的c语言程序闪退,Win10专业版软件打不开闪退怎么办?

现在用到最多的Win10系统是Win10专业版&#xff0c;用户重装Win10专业版系统的目的就是为了解决电脑遇到的问题&#xff0c;然而重装系统后还是会出现许许多多的问题&#xff0c;比如说部分软件打不开了&#xff0c;闪退的问题。如果您也遇到了相同的问题&#xff0c;下面就是小…

win10安装虚拟机闪退_win10应用商店战争机器4闪退,无法运行。

创建日期 2018/01/07 win10应用商店战争机器4闪退&#xff0c;无法运行。 日志名称: System 来源: Microsoft-Windows-DistributedCOM 日期: 2018-01-07 14:05:10 事件 ID: 10001 任务类别: 无 级别: 错误 关键字:…