Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍

已发表的技术专栏
0  grpc-go、protobuf、multus-cni 技术专栏 总入口

1  grpc-go 源码剖析与实战  文章目录

2  Protobuf介绍与实战 图文专栏  文章目录

3  multus-cni   文章目录(k8s多网络实现方案)

4  grpc、oauth2、openssl、双向认证、单向认证等专栏文章目录

1、文件级别选项的作用

主要是对xxx.proto文件生成的不同类型的语言库文件的相关设置,

  • go语言生成的库文件类似于xxx.pb.go,文件级别选项主要作用于xxx.pb.go的相关设置
  • Java语言生成的库文件类似于xxx.java,文件级别选项主要作用于xxx.java的相关设置,如
    • 设置Java类的包名,
    • 文件名称,
    • 默认文件的路径,
    • proto文件里一个message类型的消息生成一个Java文件等等

2、文件级别选项,主要分为两大类:

  • 一类是,Protobuf 默认支持的选项,
  • 一类是,Protobuf 支持自定义文件级别选项

3、Protobuf 文件级别选项,默认支持哪些文件级别的选项

打开description.proto文件,找到FileOptions即可
Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第1张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第2张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第3张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第4张图片

下面是文本形式:方便搜索查询。

message FileOptions {

  // Sets the Java package where classes generated from this .proto will be
  // placed.  By default, the proto package is used, but this is often
  // inappropriate because proto packages do not normally start with backwards
  // domain names.
  optional string java_package = 1;


  // If set, all the classes from the .proto file are wrapped in a single
  // outer class with the given name.  This applies to both Proto1
  // (equivalent to the old "--one_java_file" option) and Proto2 (where
  // a .proto always translates to a single class, but you may want to
  // explicitly choose the class name).
  optional string java_outer_classname = 8;

  // If set true, then the Java code generator will generate a separate .java
  // file for each top-level message, enum, and service defined in the .proto
  // file.  Thus, these types will *not* be nested inside the outer class
  // named by java_outer_classname.  However, the outer class will still be
  // generated to contain the file's getDescriptor() method as well as any
  // top-level extensions defined in the file.
  optional bool java_multiple_files = 10 [default = false];

  // This option does nothing.
  optional bool java_generate_equals_and_hash = 20 [deprecated=true];

  // If set true, then the Java2 code generator will generate code that
  // throws an exception whenever an attempt is made to assign a non-UTF-8
  // byte sequence to a string field.
  // Message reflection will do the same.
  // However, an extension field still accepts non-UTF-8 byte sequences.
  // This option has no effect on when used with the lite runtime.
  optional bool java_string_check_utf8 = 27 [default = false];


  // Generated classes can be optimized for speed or code size.
  enum OptimizeMode {
    SPEED = 1;         // Generate complete code for parsing, serialization,
                       // etc.
    CODE_SIZE = 2;     // Use ReflectionOps to implement these methods.
    LITE_RUNTIME = 3;  // Generate code using MessageLite and the lite runtime.
  }
  optional OptimizeMode optimize_for = 9 [default = SPEED];

  // Sets the Go package where structs generated from this .proto will be
  // placed. If omitted, the Go package will be derived from the following:
  //   - The basename of the package import path, if provided.
  //   - Otherwise, the package statement in the .proto file, if present.
  //   - Otherwise, the basename of the .proto file, without extension.
  optional string go_package = 11;




  // Should generic services be generated in each language?  "Generic" services
  // are not specific to any particular RPC system.  They are generated by the
  // main code generators in each language (without additional plugins).
  // Generic services were the only kind of service generation supported by
  // early versions of google.protobuf.
  //
  // Generic services are now considered deprecated in favor of using plugins
  // that generate code specific to your particular RPC system.  Therefore,
  // these default to false.  Old code which depends on generic services should
  // explicitly set them to true.
  optional bool cc_generic_services = 16 [default = false];
  optional bool java_generic_services = 17 [default = false];
  optional bool py_generic_services = 18 [default = false];
  optional bool php_generic_services = 42 [default = false];

  // Is this file deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for everything in the file, or it will be completely ignored; in the very
  // least, this is a formalization for deprecating files.
  optional bool deprecated = 23 [default = false];

  // Enables the use of arenas for the proto messages in this file. This applies
  // only to generated classes for C++.
  optional bool cc_enable_arenas = 31 [default = true];


  // Sets the objective c class prefix which is prepended to all objective c
  // generated classes from this .proto. There is no default.
  optional string objc_class_prefix = 36;

  // Namespace for generated classes; defaults to the package.
  optional string csharp_namespace = 37;

  // By default Swift generators will take the proto package and CamelCase it
  // replacing '.' with underscore and use that to prefix the types/symbols
  // defined. When this options is provided, they will use this value instead
  // to prefix the types/symbols defined.
  optional string swift_prefix = 39;

  // Sets the php class prefix which is prepended to all php generated classes
  // from this .proto. Default is empty.
  optional string php_class_prefix = 40;

  // Use this option to change the namespace of php generated classes. Default
  // is empty. When this option is empty, the package name will be used for
  // determining the namespace.
  optional string php_namespace = 41;

  // Use this option to change the namespace of php generated metadata classes.
  // Default is empty. When this option is empty, the proto file name will be
  // used for determining the namespace.
  optional string php_metadata_namespace = 44;

  // Use this option to change the package of ruby generated classes. Default
  // is empty. When this option is not set, the package name will be used for
  // determining the ruby package.
  optional string ruby_package = 45;


  // The parser stores options it doesn't recognize here.
  // See the documentation for the "Options" section above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message.
  // See the documentation for the "Options" section above.
  extensions 1000 to max;

  reserved 38;
}

接下来的文章中,会找一些常见的介绍。

4、Protobuf option java_package 如何设置Java类的包名?(两种方式)

4.1、方式一:通过option java_package = “包名”;

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第5张图片

java_package只有在生成Java语言代码库的情况时起作用,其他语言不起作用。

4.2、方式二:package 包名

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第6张图片

4.3、option java_package 跟 package 哪个级别高呢?

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第7张图片

5、Protobuf option java_outer_classname 如何设置Java类的文件名、类名、默认的文件名称、类名?

通过option java_outer_classname = “”;
Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第8张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第9张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第10张图片

6、Protobuf option java_multiple_files如何实现一个消息生成一个Java文件?

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第11张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第12张图片

7、Protobuf option optimize_for 根据使用场景优化生成的代码库?

//仅是我个人的理解
通过protoc生成的代码库会应用在不同的场景中,如

  • 某些场景对序列化、解析等操作的要求比较高
  • 某些场景对序列化、解析等操作的要求并不高
  • 某些场景并不需要代码库提供的API所有接口

针对上面的三个特性,option optimize_for 对应三个有效值,如

  • SPEED (默认) ,使用场景:对序列化等操作的要求比较高
  • CODE_SIZE,使用场景:对序列化等操作的要求并不高,但,提供的API接口跟SPEED模式是一样的,只是生成的代码库文件大小偏少。
  • LITE_RUNTIME,使用场景:如某些手机平台,并不需要所有的API接口

使用方式如下:

option optimize_for = CODE_SIZE;

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第13张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第14张图片

optimize_for对c++、Java 、某些第三方代码生成器起作用。

8、Protobuf option go_package 生成go语言包

针对go语言的option 选项目前只有 go_package一个。

8.1、go_package选项值的格式:

8.1.1、方式一:option go_package=”生成xxx.pb.go文件路径;xxx.pb.go包名”;

go_package的值,是有两部分组成,由”;”作为分隔符链接

  • 第一部分,是生成xxx.pb.go文件的路径,
  • 第二部分,是生成xxx.pb.go文件的包名;注意,是包名,并非设置的是文件名

8.1.2、方式二:option go_package=”生成xxx.pb.go文件路径”;

即,在使用的时候,第二部分非必须写。

例如1:
option go_package=”google/pb/test”;

此时,会将生成的xxx.pb.go文件存储在google/pb/test路径下;其中,包名,默认为test;

将”google/pb/test”中的/作为分隔符的。

例如2:
option go_package=”google/pb.test”;

此时,会将生成的xxx.pb.go文件存储在google/pb.test路径下;其中,包名,默认为pb_test;

8.2、测试用例:option go_package=”pb.example”;

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第15张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第16张图片

8.3、测试用例:option go_package=”google/pb.example”;

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第17张图片

将. 改成 _ 拼接为包名

8.4、测试用例:option go_package=”google/pb/test;vip/user”;

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第18张图片

9、Protobuf extend 自定义扩展文件级别选项(FileOpitons类型)

在proto3版本中不支持extensions关键字,

但是,支持extend关键字。

可以通过extend关键字对proto2版本声明的消息进行扩展。

比方说,对google/protobuf/descriptor.proto文件中FileOptions消息进行字段扩展。
(google/protobuf/descriptor.proto文件已经上传到了百度网盘里)

链接: https://pan.baidu.com/s/1RNDYSmX38xFc_O7iDeGdcw 提取码: t3w6

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第19张图片

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第20张图片

也就是说,可以对FileOptions消息进行扩展,标识号从1000开始。

测试用例:

9.1、待测试fileoptions.proto文件内容

syntax = "proto3";

import "google/protobuf/descriptor.proto";

extend google.protobuf.FileOptions {
    string file_name = 1000;
    int32 age = 1001;
}

option (file_name) = "xx.zz";
option (age)=18;

message UserInfo{
    string name=1;
}

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第21张图片

9.2、测试:如何获取到文件级别的字段file_name呢?

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第22张图片

import (
	"testing"
	"google.golang.org/protobuf/proto"
	"github.com/CodisLabs/codis/pkg/utils/log"
	"github.com/golang/protobuf/descriptor"
)

func TestFileOptions(t *testing.T) {
	ui := &UserInfo{Name:"user"}

	uiFile, _ := descriptor.MessageDescriptorProto(ui)

	efn := proto.GetExtension(uiFile.Options, E_FileName)
	fnString := efn.(string)
	log.Infof("---FileOptions--FileName:%v", fnString)
}

其他文件级别的扩展字段获取方式是一样的。

9.3、测试:更新文件级别的扩展字段的默认值

Protobuf 介绍与实战34:protobuf FileOptions 文件级别 选项介绍_第23张图片

下一篇文章
  Protobuf MethodOptions 方法 选项介绍

你可能感兴趣的:(grpc-go,kubernetes,protobuf,golang,架构师)