protobuf-Java使用.md

news2024/10/6 16:25:56

protobuf 环境配置

1、安装编译器

下载地址

直接解压缩。

2、配置环境变量

环境变量Path 中增加安装目录的路径

3、检查是否配置成功

protoc
Usage: protoc [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
  -IPATH, --proto_path=PATH   Specify the directory in which to search for
                              imports.  May be specified multiple times;
                              directories will be searched in order.  If not
                              given, the current working directory is used.
                              If not found in any of the these directories,
                              the --descriptor_set_in descriptors will be
                              checked for required proto file.
  --version                   #版本
  -h, --help                  #帮助
  --encode=MESSAGE_TYPE       Read a text-format message of the given type
                              from standard input and write it in binary
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their imports.
  --deterministic_output      When using --encode, ensure map fields are
                              deterministically ordered. Note that this order
                              is not canonical, and changes across builds or
                              releases of protoc.
  --decode=MESSAGE_TYPE       Read a binary message of the given type from
                              standard input and write it in text format
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their imports.
  --decode_raw                Read an arbitrary protocol message from
                              standard input and write the raw tag/value
                              pairs in text format to standard output.  No
                              PROTO_FILES should be given when using this
                              flag.
  --descriptor_set_in=FILES   Specifies a delimited list of FILES
                              each containing a FileDescriptorSet (a
                              protocol buffer defined in descriptor.proto).
                              The FileDescriptor for each of the PROTO_FILES
                              provided will be loaded from these
                              FileDescriptorSets. If a FileDescriptor
                              appears multiple times, the first occurrence
                              will be used.
  -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,
    --descriptor_set_out=FILE defined in descriptor.proto) containing all of
                              the input files to FILE.
  --include_imports           When using --descriptor_set_out, also include
                              all dependencies of the input files in the
                              set, so that the set is self-contained.
  --include_source_info       When using --descriptor_set_out, do not strip
                              SourceCodeInfo from the FileDescriptorProto.
                              This results in vastly larger descriptors that
                              include information about the original
                              location of each decl in the source file as
                              well as surrounding comments.
  --retain_options            When using --descriptor_set_out, do not strip
                              any options from the FileDescriptorProto.
                              This results in potentially larger descriptors
                              that include information about options that were
                              only meant to be useful during compilation.
  --dependency_out=FILE       Write a dependency output file in the format
                              expected by make. This writes the transitive
                              set of input file paths to FILE
  --error_format=FORMAT       Set the format in which to print errors.
                              FORMAT may be 'gcc' (the default) or 'msvs'
                              (Microsoft Visual Studio format).
  --fatal_warnings            Make warnings be fatal (similar to -Werr in
                              gcc). This flag will make protoc return
                              with a non-zero exit code if any warnings
                              are generated.
  --print_free_field_numbers  Print the free field numbers of the messages
                              defined in the given proto files. Extension ranges
                              are counted as occupied fields numbers.
  --enable_codegen_trace      Enables tracing which parts of protoc are
                              responsible for what codegen output. Not supported
                              by all backends or on all platforms.
  --plugin=EXECUTABLE         Specifies a plugin executable to use.
                              Normally, protoc searches the PATH for
                              plugins, but you may specify additional
                              executables not in the path using this flag.
                              Additionally, EXECUTABLE may be of the form
                              NAME=PATH, in which case the given plugin name
                              is mapped to the given executable even if
                              the executable's own name differs.
  --cpp_out=OUT_DIR           Generate C++ header and source.
  --csharp_out=OUT_DIR        Generate C# source file.
  --java_out=OUT_DIR          Generate Java source file.
  --kotlin_out=OUT_DIR        Generate Kotlin file.
  --objc_out=OUT_DIR          Generate Objective-C header and source.
  --php_out=OUT_DIR           Generate PHP source file.
  --pyi_out=OUT_DIR           Generate python pyi stub.
  --python_out=OUT_DIR        Generate Python source file.
  --ruby_out=OUT_DIR          Generate Ruby source file.
  --rust_out=OUT_DIR          Generate Rust sources.
  @<filename>                 Read options and filenames from file. If a
                              relative file path is specified, the file
                              will be searched in the working directory.
                              The --proto_path option will not affect how
                              this argument file is searched. Content of
                              the file will be expanded in the position of
                              @<filename> as in the argument list. Note
                              that shell expansion is not applied to the
                              content of the file (i.e., you cannot use
                              quotes, wildcards, escapes, commands, etc.).
                              Each line corresponds to a single argument,
                              even if it contains spaces.

E:\setups\protoc-25.0-win64\bin\protoc.exe --java_out=E:\projects_study\research\base\target Data2.proto 

idea 中使用 protobuf

1、idea 安装 protobuf 相关插件

安装插件:

  • protobuf generator:根据 .proto 文件来生成 proto 对象
  • pojo to proto:类文件-右键-PojoProto, 将简单Java类型转成proto message拷贝至剪贴板

2、配置全局 protobuf

image-20240119192758808

人工生成Java文件

1、引入包

        <!--  protobuf 支持 Java 核心包-->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.21.11</version>
        </dependency>

      <!--  proto 与 Json 互转会用到-->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.15.3</version>
        </dependency>

2、编写.proto文件

//使用 proto3 语法 ,未指定则使用proto2
syntax = "proto3";

//生成 proto 文件所在包路径
package demon.research.proto;

//生成的 proto 文件所在包路径
option java_package = "demon.research.proto";

//生成的 proto 文件名
option java_outer_classname="DataGen";

//message关键字 定义一个消息体。
message DataOriginal{
  int32 id = 1;
  string code = 2;
  string name = 3;
}

3、生成Java 文件

直接在文件上点击右键,quick gen protobuf here,则在此目录根据包生成一个java文件,名字为Data.java.

quick gen protobuf rules 则根据配置的规则,把java文件生成在指定的目录。

然后把生成的Java文件,copy到java类目录下

4、序列化和反序列化

        //初始化数据
        DataGen.DataOriginal.Builder builder = DataGen.DataOriginal.newBuilder();

        builder.setId(1).setCode("001").setName("张三").build();

        //序列化
        DataGen.DataOriginal build = builder.build();
        //转换成字节数组
        byte[] s = build.toByteArray();
        System.out.println("protobuf数据bytes[]:" + Arrays.toString(s));
        System.out.println("protobuf序列化大小: " + s.length);

        DataGen.DataOriginal data = null;
        String jsonObject = null;
        try {
            //反序列化
            data = DataGen.DataOriginal.parseFrom(s);
            //转 json
            jsonObject = JsonFormat.printer().print(data);
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Json格式化结果:\n" + jsonObject);
        System.out.println("Json格式化数据大小: " + jsonObject.getBytes().length);

输出结果:

protobuf数据bytes[]:[8, 1, 18, 3, 48, 48, 49, 26, 6, -27, -68, -96, -28, -72, -119]
protobuf序列化大小: 15
Json格式化结果:
{
  "id": 1,
  "code": "001",
  "name": "张三"
}
Json格式化数据大小: 50

传输的数据,确实比json格式的要小。

maven自动生成

引入插件

        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
        
        <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.21.11:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:3.21.11:exe:${os.detected.classifier}
                    </pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

默认.proto文件的扫描目录为: ${basedir}/src/main/proto

默认生成的文件路径为:${project.build.directory}/generated-sources/protobuf/java.

需要人工把代码放到指定目录。如果需要自动生成到指定目录,则修改指定目录。

注意:默认会把指定的目录数据都给删除掉。,可以设置clearOutputDirectory为false。

附录

参考

下载地址

生成代码

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: DataOriginal.proto

// Protobuf Java Version: 3.25.0

// java_package  设置的包名
package demon.research.proto;

//java_outer_classname 指定的类名
public final class DataGen {
    //避免修改
  private DataGen() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
    
    //构造器模式。
  public interface DataOriginalOrBuilder extends
      // @@protoc_insertion_point(interface_extends:demon.research.proto.DataOriginal)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>int32 id = 1;</code>
     * @return The id.
     */
    int getId();

     
     //******************* 会为字符串类型 生成序列化 方法。
    /**
     * <code>string code = 2;</code>
     * @return The code.
     */
    String getCode();
    /**
     * <code>string code = 2;</code>
     * @return The bytes for code.
     */
    com.google.protobuf.ByteString
        getCodeBytes();

    /**
     * <code>string name = 3;</code>
     * @return The name.
     */
    String getName();
    /**
     * <code>string name = 3;</code>
     * @return The bytes for name.
     */
    com.google.protobuf.ByteString
        getNameBytes();
  }
  /**
   * <pre>
   *message关键字 定义一个消息体。
   * </pre>
   *
   * Protobuf type {@code demon.research.proto.DataOriginal}
   */
  public static final class DataOriginal extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:demon.research.proto.DataOriginal)
      DataOriginalOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use DataOriginal.newBuilder() to construct.
    private DataOriginal(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private DataOriginal() {
      code_ = "";
      name_ = "";
    }

    @Override
    @SuppressWarnings({"unused"})
    protected Object newInstance(
        UnusedPrivateParameter unused) {
      return new DataOriginal();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return DataGen.internal_static_demon_research_proto_DataOriginal_descriptor;
    }

    @Override
    protected FieldAccessorTable
        internalGetFieldAccessorTable() {
      return DataGen.internal_static_demon_research_proto_DataOriginal_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              DataOriginal.class, Builder.class);
    }

    public static final int ID_FIELD_NUMBER = 1;
    private int id_ = 0;
    /**
     * <code>int32 id = 1;</code>
     * @return The id.
     */
    @Override
    public int getId() {
      return id_;
    }

    public static final int CODE_FIELD_NUMBER = 2;
    @SuppressWarnings("serial")
    private volatile Object code_ = "";
    /**
     * <code>string code = 2;</code>
     * @return The code.
     */
    @Override
    public String getCode() {
      Object ref = code_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        code_ = s;
        return s;
      }
    }
    /**
     * <code>string code = 2;</code>
     * @return The bytes for code.
     */
    @Override
    public com.google.protobuf.ByteString
        getCodeBytes() {
      Object ref = code_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        code_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int NAME_FIELD_NUMBER = 3;
    @SuppressWarnings("serial")
    private volatile Object name_ = "";
    /**
     * <code>string name = 3;</code>
     * @return The name.
     */
    @Override
    public String getName() {
      Object ref = name_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        name_ = s;
        return s;
      }
    }
    /**
     * <code>string name = 3;</code>
     * @return The bytes for name.
     */
    @Override
    public com.google.protobuf.ByteString
        getNameBytes() {
      Object ref = name_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (id_ != 0) {
        output.writeInt32(1, id_);
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(code_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, code_);
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, name_);
      }
      getUnknownFields().writeTo(output);
    }

    @Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (id_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, id_);
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(code_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, code_);
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, name_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @Override
    public boolean equals(final Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof DataOriginal)) {
        return super.equals(obj);
      }
      DataOriginal other = (DataOriginal) obj;

      if (getId()
          != other.getId()) return false;
      if (!getCode()
          .equals(other.getCode())) return false;
      if (!getName()
          .equals(other.getName())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + ID_FIELD_NUMBER;
      hash = (53 * hash) + getId();
      hash = (37 * hash) + CODE_FIELD_NUMBER;
      hash = (53 * hash) + getCode().hashCode();
      hash = (37 * hash) + NAME_FIELD_NUMBER;
      hash = (53 * hash) + getName().hashCode();
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static DataOriginal parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static DataOriginal parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static DataOriginal parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static DataOriginal parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static DataOriginal parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static DataOriginal parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static DataOriginal parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static DataOriginal parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    public static DataOriginal parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }

    public static DataOriginal parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static DataOriginal parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static DataOriginal parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(DataOriginal prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @Override
    protected Builder newBuilderForType(
        BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     *message关键字 定义一个消息体。
     * </pre>
     *
     * Protobuf type {@code demon.research.proto.DataOriginal}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:demon.research.proto.DataOriginal)
        DataOriginalOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return DataGen.internal_static_demon_research_proto_DataOriginal_descriptor;
      }

      @Override
      protected FieldAccessorTable
          internalGetFieldAccessorTable() {
        return DataGen.internal_static_demon_research_proto_DataOriginal_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                DataOriginal.class, Builder.class);
      }

      // Construct using demon.research.proto.DataGen.DataOriginal.newBuilder()
      private Builder() {

      }

      private Builder(
          BuilderParent parent) {
        super(parent);

      }
      @Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        id_ = 0;
        code_ = "";
        name_ = "";
        return this;
      }

      @Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return DataGen.internal_static_demon_research_proto_DataOriginal_descriptor;
      }

      @Override
      public DataOriginal getDefaultInstanceForType() {
        return DataOriginal.getDefaultInstance();
      }

      @Override
      public DataOriginal build() {
        DataOriginal result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @Override
      public DataOriginal buildPartial() {
        DataOriginal result = new DataOriginal(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(DataOriginal result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.id_ = id_;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.code_ = code_;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.name_ = name_;
        }
      }

      @Override
      public Builder clone() {
        return super.clone();
      }
      @Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          Object value) {
        return super.setField(field, value);
      }
      @Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          Object value) {
        return super.addRepeatedField(field, value);
      }
      @Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof DataOriginal) {
          return mergeFrom((DataOriginal)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(DataOriginal other) {
        if (other == DataOriginal.getDefaultInstance()) return this;
        if (other.getId() != 0) {
          setId(other.getId());
        }
        if (!other.getCode().isEmpty()) {
          code_ = other.code_;
          bitField0_ |= 0x00000002;
          onChanged();
        }
        if (!other.getName().isEmpty()) {
          name_ = other.name_;
          bitField0_ |= 0x00000004;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @Override
      public final boolean isInitialized() {
        return true;
      }

      @Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                id_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 18: {
                code_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                name_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int id_ ;
      /**
       * <code>int32 id = 1;</code>
       * @return The id.
       */
      @Override
      public int getId() {
        return id_;
      }
      /**
       * <code>int32 id = 1;</code>
       * @param value The id to set.
       * @return This builder for chaining.
       */
      public Builder setId(int value) {

        id_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <code>int32 id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        id_ = 0;
        onChanged();
        return this;
      }

      private Object code_ = "";
      /**
       * <code>string code = 2;</code>
       * @return The code.
       */
      public String getCode() {
        Object ref = code_;
        if (!(ref instanceof String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          String s = bs.toStringUtf8();
          code_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      /**
       * <code>string code = 2;</code>
       * @return The bytes for code.
       */
      public com.google.protobuf.ByteString
          getCodeBytes() {
        Object ref = code_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (String) ref);
          code_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string code = 2;</code>
       * @param value The code to set.
       * @return This builder for chaining.
       */
      public Builder setCode(
          String value) {
        if (value == null) { throw new NullPointerException(); }
        code_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <code>string code = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearCode() {
        code_ = getDefaultInstance().getCode();
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      /**
       * <code>string code = 2;</code>
       * @param value The bytes for code to set.
       * @return This builder for chaining.
       */
      public Builder setCodeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        code_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }

      private Object name_ = "";
      /**
       * <code>string name = 3;</code>
       * @return The name.
       */
      public String getName() {
        Object ref = name_;
        if (!(ref instanceof String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          String s = bs.toStringUtf8();
          name_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      /**
       * <code>string name = 3;</code>
       * @return The bytes for name.
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string name = 3;</code>
       * @param value The name to set.
       * @return This builder for chaining.
       */
      public Builder setName(
          String value) {
        if (value == null) { throw new NullPointerException(); }
        name_ = value;
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <code>string name = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearName() {
        name_ = getDefaultInstance().getName();
        bitField0_ = (bitField0_ & ~0x00000004);
        onChanged();
        return this;
      }
      /**
       * <code>string name = 3;</code>
       * @param value The bytes for name to set.
       * @return This builder for chaining.
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        name_ = value;
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      @Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:demon.research.proto.DataOriginal)
    }

    // @@protoc_insertion_point(class_scope:demon.research.proto.DataOriginal)
    private static final DataOriginal DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new DataOriginal();
    }

    public static DataOriginal getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<DataOriginal>
        PARSER = new com.google.protobuf.AbstractParser<DataOriginal>() {
      @Override
      public DataOriginal parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<DataOriginal> parser() {
      return PARSER;
    }

    @Override
    public com.google.protobuf.Parser<DataOriginal> getParserForType() {
      return PARSER;
    }

    @Override
    public DataOriginal getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_demon_research_proto_DataOriginal_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_demon_research_proto_DataOriginal_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    String[] descriptorData = {
      "\n\022DataOriginal.proto\022\024demon.research.pro" +
      "to\"6\n\014DataOriginal\022\n\n\002id\030\001 \001(\005\022\014\n\004code\030\002" +
      " \001(\t\022\014\n\004name\030\003 \001(\tB\037\n\024demon.research.pro" +
      "toB\007DataGenb\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        });
    internal_static_demon_research_proto_DataOriginal_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_demon_research_proto_DataOriginal_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_demon_research_proto_DataOriginal_descriptor,
        new String[] { "Id", "Code", "Name", });
  }

  // @@protoc_insertion_point(outer_class_scope)
}

1、DataGen 类只提供框架方法。

public final class DataGen {
  private DataGen() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
    
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_demon_research_proto_DataOriginal_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_demon_research_proto_DataOriginal_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
    

2、接口 DataOriginalOrBuilder,只提供了get方法。

int getId();
String getCode();
com.google.protobuf.ByteString         getCodeBytes();
String getName();
 com.google.protobuf.ByteString          getNameBytes();

3、类DataOriginal 继承类 com.google.protobuf.GeneratedMessageV3 ,实现接口 DataOriginalOrBuilder提供了get方法,并保存了数据。同时提供了序列化与反序列化能力

   public static final int ID_FIELD_NUMBER = 1;
    private int id_ = 0;
    /**
     * <code>int32 id = 1;</code>
     * @return The id.
     */
    @Override
    public int getId() {
      return id_;
    }

4、类Builder 继承类 com.google.protobuf.GeneratedMessageV3.Builder<Builder> ,实现接口 DataOriginalOrBuilder提供了get/set方法,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1400405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于程序员的未来的这件事情,我是这么看的!

关于程序员的未来在哪里&#xff1f;很多想做程序员以及已经入坑的程序员都想知道&#xff0c;我作为一名工龄超过12年的资深大龄程序员&#xff0c;我其实也想知道&#xff0c;我也没办法确定程序员的未来在哪里。 或者我也不知道&#xff0c;为什么互联网当初招聘那么多的程…

10 Hadoop的安全模式及权限介绍

1、HDFS工作流程 启动NameNode&#xff0c;NameNode加载fsimage到内存&#xff0c;对内存数据执行edits log日志中的事务操作。文件系统元数据内存镜像加载完毕&#xff0c;进行fsimage和edits log日志的合并&#xff0c;并创建新的fsimage文件和一个空的edits log日志文件。N…

跟着cherno手搓游戏引擎【8】按键和鼠标的KeyCode

自定义KeyCode 先把glfw3.h里的KeyCode的定义抄到咱这里来。 在YOTO下创建KeyCode.h: #pragma once#ifdef YT_PLATFORM_WINDOWS///从glfw3中拿的 #define YT_KEY_SPACE 32 #define YT_KEY_APOSTROPHE 39 /* */ #define YT_KEY_COMMA 44…

node.js项目express的初始化

目录 1.初始化项目2.配置跨域3.开始编写API3.1准备3.2路由处理函数router_make下的user.js3.3路由模块router下的user.js3.4入口文件app.js里面去新增这段代码3.5启动项目进行测试 &#x1f44d; 点赞&#xff0c;你的认可是我创作的动力&#xff01; ⭐️ 收藏&#xff0c;你…

如何在浏览器上设置 VPN 网络虚拟专用网络

如何在DT浏览器上设置 VPN 网络 虚拟专用网络&#xff08;VPN&#xff09;是一种用公用网络架设专用网络的技术。如何在DT浏览器上设置 VPN 呢&#xff0c;先下载DT浏览器&#xff0c;建议在官方网站下载最新版&#xff0c;安装&#xff0c;在DT浏览器首页点更多&#xff0c;网…

Excel·VBA合并工作簿2

其他合并工作簿的方法&#xff0c;见之前的文章《ExcelVBA合并工作簿》 目录 8&#xff0c;合并文件夹下所有工作簿中所有工作表&#xff0c;按表头汇总举例 8&#xff0c;合并文件夹下所有工作簿中所有工作表&#xff0c;按表头汇总 与之前的文章《ExcelVBA合并工作簿&#x…

3.postman动态参数、文件上传及断言

一、postman内置动态参数以及自定义的动态参数 postman内置动态参数&#xff1a; {{$timestamp}} 生成当前时间的时间戳 {{$randomint}} 生成0-1000之间的随机数 {{$guid}} 生成随机guid字符串 自定义动态参数&#xff1a; 在请求中pre-req页面下 //手动的获得时间戳 var…

Java - 深入四大限流算法:原理、实现与应用

文章目录 Pre概述简单计数器原理实现测试优缺点 滑动窗口算法原理实现测试优缺点 漏桶算法原理实现测试优缺点 令牌桶算法原理实现测试优缺点 小结 Pre 深入理解分布式技术 - 限流 并发编程-25 高并发处理手段之消息队列思路 应用拆分思路 应用限流思路 SpringBoot - 优雅…

Spring Cloud中使用Dubbo

简介 Dubbo是一款高性能、轻量级的开源Java RPC框架&#xff0c;主要用于构建大型分布式系统。提供了三大核心能力&#xff1a;面向接口的远程方法调用&#xff0c;智能容错和负载均衡&#xff0c;以及服务自动注册和发现。 Dubbo框架主要由以下组件构成&#xff1a;Provider…

Qt打包成为exe遇到的问题及其解决方法

Qt打包成为exe遇到的问题及其解决方法 文章目录 Qt打包成为exe遇到的问题及其解决方法0. 前言1. 使用Release编译工程2. 利用windeployqt工具来找出和复制依赖项3. 解决 Qt Location /Qt Positioning is not installed4. 利用Enigma virtual box打包 .exe程序5. dependency wal…

C++从小白到初级工程师【个人学习笔记】

目录 1.背景2.基础二维数组概念二维数组定义方式 二维数组数组名称概念例子 1.背景 C作为能和计算机硬件打交道的语言&#xff0c;在计算机世界中具有重要意义。在Android 应用层的JNI开发中&#xff0c;Android framework层、驱动层、kernel层均使用广泛。 相应的&#xff0c…

无法找到mfc100.dll的解决方法分享,如何快速修复mfc100.dll文件

在日常使用电脑时&#xff0c;我们可能会碰到一些系统错误提示&#xff0c;比如“无法找到mfc100.dll”的信息。这种错误通常会阻碍代码的执行或某些应用程序的启动。为了帮助您解决这一问题&#xff0c;本文将深入探讨其成因&#xff0c;并提供几种不同的mfc100.dll解决方案。…

Pycharm Terminal 无法激活conda环境

1.问题 Failed to activate conda environment. Please open Anaconda prompt, and run conda init powershell there. 这导致我们无法在Pycharm中使用conda命令 2.解决办法 修改为第二个&#xff0c;然后重启Terminal 再打开时发现已经是当前的conda环境

68. redis计数与限流中incr+expire的坑以及解决办法(Lua+TTL)

文章目录 一、简介二、代码演进第一版代码&#xff08;存在bug隐患&#xff09;第二版代码&#xff08;几乎无隐患&#xff09;第三版代码(完美无瑕&#xff09; 一、简介 在日常工作中&#xff0c;经常会遇到对某种操作进行频次控制或者统计次数的需求&#xff0c;此时常用的…

一起来看看,C++11标准,那些超实用的新特性有哪些?

C11标准是 ISO/IEC 14882:2011 - Information technology -- Programming languages -- C 的简称&#xff0c;也称为C0x。它由国际标准化组织&#xff08;ISO&#xff09;和国际电工委员会&#xff08;IEC&#xff09;旗下的C标准委员会&#xff08;ISO/IEC JTC1/SC22/WG21&…

基于华为MRS3.2.0实时Flink消费Kafka落盘至HDFS的Hive外部表的调度方案

文章目录 1 Kafka1.1 Kerberos安全模式的认证与环境准备1.2 创建一个测试主题1.3 消费主题的接收测试 2 Flink1.1 Kerberos安全模式的认证与环境准备1.2 Flink任务的开发 3 HDFS与Hive3.1 Shell脚本的编写思路3.2 脚本测试方法 4 DolphinScheduler 该需求为实时接收对手Topic&a…

四个简单的bat脚本

Windows11 最大劝退点就是这个右键菜单&#xff0c;复制粘贴都变成一点点的小图标&#xff0c;最气人的是点击底部的显示更多选项才能展示全部功能。让许多本来点一次就能完成的操作变成两次。其实使用一个小命令就能修改回win10版本的菜单。四个简单的bat脚本&#xff0c;能完…

Object.prototype.toString.call个人理解

文章目录 这段代码的常见用处参考文献&#xff1a; 拆分理解1、Object.prototype.toString小问题参考文献&#xff1a; 2、call函数的作用参考文献 3、继续深入一些&#xff08;这部分内容是个人理解&#xff0c;没有明确文献支撑&#xff09; 这段代码的常见用处 Object.prot…

这可能是最全面的计算机组成原理面试八股文了

第一章 计算机系统概述 “较简单&#xff0c;不做过多赘述&#xff0c;后面会详细学到” 第一节 计算机系统层次结构 1.计算机系统的基本组成&#xff1a;硬件软件 2.计算机硬件的基本组成&#xff1a;运算器存储器控制器输入设备输出设备 3.系统软件和应用软件 系统软件…

.NET国产化改造探索(六)、银河麒麟操作系统中安装多个.NET版本

随着时代的发展以及近年来信创工作和…废话就不多说了&#xff0c;这个系列就是为.NET遇到国产化需求的一个闭坑系列。接下来&#xff0c;看操作。 上一篇文章介绍了如何在银河麒麟操作系统上&#xff0c;使用Nginx.NET程序实现自启动。本文介绍下如何在一个环境中&#xff0c;…