1. 程式人生 > >grpc雙向流式呼叫——構建一個簡單的流資料分析器

grpc雙向流式呼叫——構建一個簡單的流資料分析器

傳送門:

關於grpc,之前已經基於循序漸進的原則和大家聊過簡單呼叫,服務端流式呼叫和客戶端流式呼叫。那麼我們今天聊的grpc應該就是雙向流式呼叫了。相對之前的有所複雜,但是其實有了前面服務端流式呼叫和客戶端流式呼叫的基礎,雙向流式呼叫其實只是兩者的結合,非常簡單。
本次雙向流式呼叫的實驗,我們應用場景和之前的客戶端流式呼叫類似,也是客戶端傳過來一串資料,服務端進行資料的處理,將資料的統計資訊作為返回結果返回給客戶端。不過這一次我們不再像客戶端流式呼叫那樣等待客戶端傳送完畢再返回結果,而是在客戶端每次傳過來一個數據時就返回一個結果。
本篇文章主要內容如下:

  1. 建立專案
  2. 定義服務
  3. 建立服務端
  4. 建立客戶端
  5. 執行實驗

建立專案

這次專案的結構和客戶端流式呼叫中的差不多,專案中主要包含了一個server和一個client模組。如下圖所示:
圖片.png
然後還是在總的專案的pom.xml檔案中新增依賴,這次我們也是新增grpc-all的依賴,較為方便,另外slf4j的依賴用於記錄日誌。另外,需要注意的是需要加入protobuf的maven編譯外掛,否則無法通過maven對proto檔案進行編譯。具體內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.sunny</groupId> <artifactId>grpc-bi-stream</artifactId
>
<packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>grpcserver</module> <module>grpcclient</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <grpc.version>1.12.0</grpc.version> <protoc.version>3.5.1-1</protoc.version> </properties> <dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-all</artifactId> <version>${grpc.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> </dependency> </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.5.0.Final</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.5.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

兩個模組中的依賴繼承專案的依賴即可,本實驗中無需增加其他內容。

定義服務

這次定義的服務和客戶端流式呼叫的例子類似,只不過在返回的部分增加了一個stream的關鍵字,表示服務端返回結果也是流式的。

syntax = "proto3";

//生成多檔案,可以將類都生成在一個檔案中
option java_multiple_files = false;
//包名
option java_package = "io.grpc.examples.calculate";
//生成的類名
option java_outer_classname = "CalculateProto";

package calculate;

// 定義服務
service CalculateService {
    // 服務中的方法,傳過來一個Value型別的流,返回一個Result型別的流資訊
    rpc getResult (stream Value) returns (stream Result) {}
}
//定義Value訊息型別,用於客戶端訊息
message Value {
    int32 value = 1;
}
//定義Result訊息型別,包含總和,數字數量和平均值,用於服務端訊息返回
message Result {
    int32 sum = 1;
    int32 cnt = 2;
    double avg = 3;
}

具體服務內容的解釋,大家通過註釋或者我的上一篇文章應該很容易就可以看懂了。感興趣的童鞋可以深入學習一下protocol buffer的語法。值得一提的是,這裡Sunny並未選擇將類生成多個檔案,而是將所有編譯得到的類都放到一個檔案中。這裡給大家展示一下編譯得到的類的程式碼。
CalculateServiceGrpc.java:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package io.grpc.examples.calculate;

import com.google.protobuf.Descriptors.FileDescriptor;
import io.grpc.BindableService;
import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ExperimentalApi;
import io.grpc.MethodDescriptor;
import io.grpc.ServerServiceDefinition;
import io.grpc.ServiceDescriptor;
import io.grpc.MethodDescriptor.MethodType;
import io.grpc.examples.calculate.CalculateProto.Result;
import io.grpc.examples.calculate.CalculateProto.Value;
import io.grpc.protobuf.ProtoFileDescriptorSupplier;
import io.grpc.protobuf.ProtoMethodDescriptorSupplier;
import io.grpc.protobuf.ProtoServiceDescriptorSupplier;
import io.grpc.protobuf.ProtoUtils;
import io.grpc.stub.AbstractStub;
import io.grpc.stub.ClientCalls;
import io.grpc.stub.ServerCalls;
import io.grpc.stub.StreamObserver;
import io.grpc.stub.ServerCalls.BidiStreamingMethod;
import io.grpc.stub.ServerCalls.ClientStreamingMethod;
import io.grpc.stub.ServerCalls.ServerStreamingMethod;
import io.grpc.stub.ServerCalls.UnaryMethod;

public final class CalculateServiceGrpc {
    public static final String SERVICE_NAME = "calculate.CalculateService";
    /** @deprecated */
    @Deprecated
    @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
    public static final MethodDescriptor<Value, Result> METHOD_GET_RESULT = getGetResultMethodHelper();
    private static volatile MethodDescriptor<Value, Result> getGetResultMethod;
    private static final int METHODID_GET_RESULT = 0;
    private static volatile ServiceDescriptor serviceDescriptor;

    private CalculateServiceGrpc() {
    }

    @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
    public static MethodDescriptor<Value, Result> getGetResultMethod() {
        return getGetResultMethodHelper();
    }

    private static MethodDescriptor<Value, Result> getGetResultMethodHelper() {
        MethodDescriptor<Value, Result> getGetResultMethod = getGetResultMethod;
        if (getGetResultMethod == null) {
            Class var1 = CalculateServiceGrpc.class;
            synchronized(CalculateServiceGrpc.class) {
                getGetResultMethod = getGetResultMethod;
                if (getGetResultMethod == null) {
                    getGetResultMethod = getGetResultMethod = MethodDescriptor.newBuilder().setType(MethodType.BIDI_STREAMING).setFullMethodName(MethodDescriptor.generateFullMethodName("calculate.CalculateService", "getResult")).setSampledToLocalTracing(true).setRequestMarshaller(ProtoUtils.marshaller(Value.getDefaultInstance())).setResponseMarshaller(ProtoUtils.marshaller(Result.getDefaultInstance())).setSchemaDescriptor(new CalculateServiceGrpc.CalculateServiceMethodDescriptorSupplier("getResult")).build();
                }
            }
        }

        return getGetResultMethod;
    }

    public static CalculateServiceGrpc.CalculateServiceStub newStub(Channel channel) {
        return new CalculateServiceGrpc.CalculateServiceStub(channel);
    }

    public static CalculateServiceGrpc.CalculateServiceBlockingStub newBlockingStub(Channel channel) {
        return new CalculateServiceGrpc.CalculateServiceBlockingStub(channel);
    }

    public static CalculateServiceGrpc.CalculateServiceFutureStub newFutureStub(Channel channel) {
        return new CalculateServiceGrpc.CalculateServiceFutureStub(channel);
    }

    public static ServiceDescriptor getServiceDescriptor() {
        ServiceDescriptor result = serviceDescriptor;
        if (result == null) {
            Class var1 = CalculateServiceGrpc.class;
            synchronized(CalculateServiceGrpc.class) {
                result = serviceDescriptor;
                if (result == null) {
                    serviceDescriptor = result = ServiceDescriptor.newBuilder("calculate.CalculateService").setSchemaDescriptor(new CalculateServiceGrpc.CalculateServiceFileDescriptorSupplier()).addMethod(getGetResultMethodHelper()).build();
                }
            }
        }

        return result;
    }

    private static final class CalculateServiceMethodDescriptorSupplier extends CalculateServiceGrpc.CalculateServiceBaseDescriptorSupplier implements ProtoMethodDescriptorSupplier {
        private final String methodName;

        CalculateServiceMethodDescriptorSupplier(String methodName) {
            this.methodName = methodName;
        }

        public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
            return this.getServiceDescriptor().findMethodByName(this.methodName);
        }
    }

    private static final class CalculateServiceFileDescriptorSupplier extends CalculateServiceGrpc.CalculateServiceBaseDescriptorSupplier {
        CalculateServiceFileDescriptorSupplier() {
        }
    }

    private abstract static class CalculateServiceBaseDescriptorSupplier implements ProtoFileDescriptorSupplier, ProtoServiceDescriptorSupplier {
        CalculateServiceBaseDescriptorSupplier() {
        }

        public FileDescriptor getFileDescriptor() {
            return CalculateProto.getDescriptor();
        }

        public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
            return this.getFileDescriptor().findServiceByName("CalculateService");
        }
    }

    private static final class MethodHandlers<Req, Resp> implements UnaryMethod<Req, Resp>, ServerStreamingMethod<Req, Resp>, ClientStreamingMethod<Req, Resp>, BidiStreamingMethod<Req, Resp> {
        private final CalculateServiceGrpc.CalculateServiceImplBase serviceImpl;
        private final int methodId;

        MethodHandlers(CalculateServiceGrpc.CalculateServiceImplBase serviceImpl, int methodId) {
            this.serviceImpl = serviceImpl;
            this.methodId = methodId;
        }

        public void invoke(Req request, StreamObserver<Resp> responseObserver) {
            switch(this.methodId) {
            default:
                throw new AssertionError();
            }
        }

        public StreamObserver<Req> invoke(StreamObserver<Resp> responseObserver) {
            switch(this.methodId) {
            case 0:
                return this.serviceImpl.getResult(responseObserver);
            default:
                throw new AssertionError();
            }
        }
    }

    public static final class CalculateServiceFutureStub extends AbstractStub<CalculateServiceGrpc.CalculateServiceFutureStub> {
        private CalculateServiceFutureStub(Channel channel) {
            super(channel);
        }

        private CalculateServiceFutureStub(Channel channel, CallOptions callOptions) {
            super(channel, callOptions);
        }

        protected CalculateServiceGrpc.CalculateServiceFutureStub build(Channel channel, CallOptions callOptions) {
            return new CalculateServiceGrpc.CalculateServiceFutureStub(channel, callOptions);
        }
    }

    public static final class CalculateServiceBlockingStub extends AbstractStub<CalculateServiceGrpc.CalculateServiceBlockingStub> {
        private CalculateServiceBlockingStub(Channel channel) {
            super(channel);
        }

        private CalculateServiceBlockingStub(Channel channel, CallOptions callOptions) {
            super(channel, callOptions);
        }

        protected CalculateServiceGrpc.CalculateServiceBlockingStub build(Channel channel, CallOptions callOptions) {
            return new CalculateServiceGrpc.CalculateServiceBlockingStub(channel, callOptions);
        }
    }

    public static final class CalculateServiceStub extends AbstractStub<CalculateServiceGrpc.CalculateServiceStub> {
        private CalculateServiceStub(Channel channel) {
            super(channel);
        }

        private CalculateServiceStub(Channel channel, CallOptions callOptions) {
            super(channel, callOptions);
        }

        protected CalculateServiceGrpc.CalculateServiceStub build(Channel channel, CallOptions callOptions) {
            return new CalculateServiceGrpc.CalculateServiceStub(channel, callOptions);
        }

        public StreamObserver<Value> getResult(StreamObserver<Result> responseObserver) {
            return ClientCalls.asyncBidiStreamingCall(this.getChannel().newCall(CalculateServiceGrpc.getGetResultMethodHelper(), this.getCallOptions()), responseObserver);
        }
    }

    public abstract static class CalculateServiceImplBase implements BindableService {
        public CalculateServiceImplBase() {
        }

        public StreamObserver<Value> getResult(StreamObserver<Result> responseObserver) {
            return ServerCalls.asyncUnimplementedStreamingCall(CalculateServiceGrpc.getGetResultMethodHelper(), responseObserver);
        }

        public final ServerServiceDefinition bindService() {
            return ServerServiceDefinition.builder(CalculateServiceGrpc.getServiceDescriptor()).addMethod(CalculateServiceGrpc.getGetResultMethodHelper(), ServerCalls.asyncBidiStreamingCall(new CalculateServiceGrpc.MethodHandlers(this, 0))).build();
        }
    }
}

CalculateProto.java

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package io.grpc.examples.calculate;

import com.google.protobuf.AbstractParser;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.Internal;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.Parser;
import com.google.protobuf.UnknownFieldSet;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner;
import com.google.protobuf.GeneratedMessageV3.BuilderParent;
import com.google.protobuf.GeneratedMessageV3.FieldAccessorTable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

public final class CalculateProto {
    private static final Descriptor internal_static_calculate_Value_descriptor;
    private static final FieldAccessorTable internal_static_calculate_Value_fieldAccessorTable;
    private static final Descriptor internal_static_calculate_Result_descriptor;
    private static final FieldAccessorTable internal_static_calculate_Result_fieldAccessorTable;
    private static FileDescriptor descriptor;

    private CalculateProto() {
    }

    public static void registerAllExtensions(ExtensionRegistryLite registry) {
    }

    public static void registerAllExtensions(ExtensionRegistry registry) {
        registerAllExtensions((ExtensionRegistryLite)registry);
    }

    public static FileDescriptor getDescriptor() {
        return descriptor;
    }

    static {
        String[] descriptorData = new String[]{"\n\u0016calculateService.proto\u0012\tcalculate\"\u0016\n\u0005Value\u0012\r\n\u0005value\u0018\u0001 \u0001(\u0005\"/\n\u0006Result\u0012\u000b\n\u0003sum\u0018\u0001 \u0001(\u0005\u0012\u000b\n\u0003cnt\u0018\u0002 \u0001(\u0005\u0012\u000b\n\u0003avg\u0018\u0003 \u0001(\u00012J\n\u0010CalculateService\u00126\n\tgetResult\u0012\u0010.calculate.Value\u001a\u0011.calculate.Result\"\u0000(\u00010\u0001B.\n\u001aio.grpc.examples.calculateB\u000eCalculateProtoP\u0000b\u0006proto3"};
        InternalDescriptorAssigner assigner = new InternalDescriptorAssigner() {
            public ExtensionRegistry assignDescriptors(FileDescriptor root) {
                CalculateProto.descriptor = root;
                return null;
            }
        };
        FileDescriptor.internalBuildGeneratedFileFrom(descriptorData, new FileDescriptor[0], assigner);
        internal_static_calculate_Value_descriptor = (Descriptor)getDescriptor().getMessageTypes().get(0);
        internal_static_calculate_Value_fieldAccessorTable = new FieldAccessorTable(internal_static_calculate_Value_descriptor, new String[]{"Value"});
        internal_static_calculate_Result_descriptor = (Descriptor)getDescriptor().getMessageTypes().get(1);
        internal_static_calculate_Result_fieldAccessorTable = new FieldAccessorTable(internal_static_calculate_Result_descriptor, new String[]{"Sum", "Cnt", "Avg"});
    }

    public static final class Result extends GeneratedMessageV3 implements CalculateProto.ResultOrBuilder {
        private static final long serialVersionUID = 0L;
        public static final int SUM_FIELD_NUMBER = 1;
        private int sum_;
        public static final int CNT_FIELD_NUMBER = 2;
        private int cnt_;
        public static final int AVG_FIELD_NUMBER = 3;
        private double avg_;
        private byte memoizedIsInitialized;
        private static final CalculateProto.Result DEFAULT_INSTANCE = new CalculateProto.Result();
        private static final Parser<CalculateProto.Result> PARSER = new AbstractParser<CalculateProto.Result>() {
            public CalculateProto.Result parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
                return new CalculateProto.Result(input, extensionRegistry, null);
            }
        };

        private Result(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
            super(builder);
            this.memoizedIsInitialized = -1;
        }

        private Result() {
            this.memoizedIsInitialized = -1;
            this.sum_ = 0;
            this.cnt_ = 0;
            this.avg_ = 0.0D;
        }

        public final UnknownFieldSet getUnknownFields() {
            return this.unknownFields;
        }

        private Result(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
            this();
            if (extensionRegistry == null) {
                throw new NullPointerException();
            } else {
                int mutable_bitField0_ = false;
                com.google.protobuf.UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder();

                try {
                    boolean done = false;

                    while(!done) {
                        int tag = input.readTag();
                        switch(tag) {
                        case 0:
                            done = true;
                            break;
                        case 8:
                            this.sum_ = input.readInt32();
                            break;
                        case 16:
                            this.cnt_ = input.readInt32();
                            break;
                        case 25:
                            this.avg_ = input.readDouble();
                            break;
                        default:
                            if (!this.parseUnknownFieldProto3(input, unknownFields, extensionRegistry, tag)) {
                                done = true;
                            }
                        }
                    }
                } catch (InvalidProtocolBufferException var11) {
                    throw var11.setUnfinishedMessage(this);
                } catch (IOException var12) {
                    throw (new InvalidProtocolBufferException(var12)).setUnfinishedMessage(this);
                } finally {
                    this.unknownFields = unknownFields.build();
                    this.makeExtensionsImmutable();
                }

            }
        }

        public static final Descriptor getDescriptor() {
            return CalculateProto.internal_static_calculate_Result_descriptor;
        }

        protected FieldAccessorTable internalGetFieldAccessorTable() {
            return CalculateProto.internal_static_calculate_Result_fieldAccessorTable.ensureFieldAccessorsInitialized(CalculateProto.Result.class, CalculateProto.Result.Builder.class);
        }

        public int getSum() {
            return this.sum_;
        }

        public int getCnt() {
            return this.cnt_;
        }

        public double getAvg() {
            return this.avg_;
        }

        public final boolean isInitialized() {
            byte isInitialized = this.memoizedIsInitialized;
            if (isInitialized == 1) {
                return true;
            } else if (isInitialized == 0) {
                return false;
            } else {
                this.memoizedIsInitialized = 1;
                return true;
            }
        }

        public void writeTo(CodedOutputStream output) throws IOException {
            if (this.sum_ != 0) {
                output.writeInt32(1, this.sum_);
            }

            if (this.cnt_ != 0) {
                output.writeInt32(2, this.cnt_);
            }

            if (this.avg_ != 0.0D) {
                output.writeDouble(3, this.avg_);
            }

            this.unknownFields.writeTo(output);
        }

        public int getSerializedSize() {
            int size = this.memoizedSize;
            if (size != -1) {
                return size;
            } else {
                size = 0;
                if (this.sum_ != 0) {
                    size += CodedOutputStream.computeInt32Size(1, this.sum_);
                }

                if (this.cnt_ != 0) {
                    size += CodedOutputStream.computeInt32Size(2, this.cnt_);
                }

                if (this.avg_ != 0.0D) {
                    size += CodedOutputStream.computeDoubleSize(3, this.avg_);
                }

                size += this.unknownFields.getSerializedSize();
                this.memoizedSize = size;
                return size;
            }
        }

        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            } else if (!(obj instanceof CalculateProto.Result)) {
                return super.equals(obj);
            } else {
                CalculateProto.Result other = (CalculateProto.Result)obj;
                boolean result = true;
                result = result && this.getSum() == other.getSum();
                result = result && this.getCnt() == other.getCnt();
                result = result && Double.doubleToLongBits(this.getAvg()) == Double.doubleToLongBits(other.getAvg());
                result = result && this.unknownFields.equals(other.unknownFields);
                return result;
            }
        }

        public int hashCode() {
            if (this.memoizedHashCode != 0) {
                return this.memoizedHashCode;
            } else {
                int hash = 41;
                int hash = 19 * hash + getDescriptor().hashCode();
                hash = 37 * hash + 1;
                hash = 53 * hash + this.getSum();
                hash = 37 * hash + 2;
                hash = 53 * hash + this.getCnt();
                hash = 37 * hash + 3;
                hash = 53 * hash + Internal.hashLong(Double.doubleToLongBits(this.getAvg()));
                hash = 29 * hash + this.unknownFields.hashCode();
                this.memoizedHashCode = hash;
                return hash;
            }
        }

        public static CalculateProto.Result parseFrom(ByteBuffer data) throws InvalidProtocolBufferException {
            return (CalculateProto.Result)PARSER.parseFrom(data);
        }

        public static CalculateProto.Result parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
            return (CalculateProto.Result)PARSER.parseFrom(data, extensionRegistry);
        }

        public static CalculateProto.Result parseFrom(ByteString data) throws InvalidProtocolBufferException {
            return (CalculateProto.Result)PARSER.parseFrom(data);
        }

        public static CalculateProto.Result parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
            return (CalculateProto.Result)PARSER.parseFrom(data, extensionRegistry);
        }

        public static CalculateProto.Result parseFrom(byte[] data) throws InvalidProtocolBufferException {
            return (CalculateProto.Result)PARSER.parseFrom(data);
        }

        public static CalculateProto.Result parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
            return (CalculateProto.Result)PARSER.parseFrom(data, extensionRegistry);
        }

        public static CalculateProto.Result parseFrom(InputStream input) throws IOException {
            return (CalculateProto.Result)GeneratedMessageV3.parseWithIOException(PARSER, input);
        }

        public static CalculateProto.Result parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException {
            return (CalculateProto.Result)GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
        }

        public static CalculateProto.Result parseDelimitedFrom(InputStream input) throws IOException {
            return (CalculateProto.Result)GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
        }

        public static CalculateProto.Result parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException {
            return (CalculateProto.Result)GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
        }

        public static CalculateProto.Result parseFrom(CodedInputStream input) throws IOException {
            return (CalculateProto.Result)GeneratedMessageV3.parseWithIOException(PARSER, input);
        }

        public static CalculateProto.Result parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException {
            return (CalculateProto.Result)GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
        }

        public CalculateProto.Result.Builder newBuilderForType() {
            return newBuilder();
        }

        public static CalculateProto.Result.Builder newBuilder() {
            return DEFAULT_INSTANCE.toBuilder();
        }

        public static CalculateProto.Result.Builder newBuilder(CalculateProto.Result prototype) {
            return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
        }

        public CalculateProto.Result.Builder toBuilder() {
            return this == DEFAULT_INSTANCE ? new CalculateProto.Result.Builder(null) : (new CalculateProto.Result.Builder(null)).mergeFrom(this);
        }

        protected CalculateProto.Result.Builder newBuilderForType(BuilderParent parent) {
            CalculateProto.Result.Builder builder = new CalculateProto.Result.Builder(parent, null);
            return builder;
        }

        public static CalculateProto.Result getDefaultInstance() {
            return DEFAULT_INSTANCE;
        }

        public static Parser<CalculateProto.Result> parser() {
            return PARSER;
        }

        public Parser<CalculateProto.Result> getParserForType() {
            return PARSER;
        }

        public CalculateProto.Result getDefaultInstanceForType() {
            return DEFAULT_INSTANCE;
        }

        public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<CalculateProto.Result.Builder> implements CalculateProto.ResultOrBuilder {
            private int sum_;
            private int cnt_;
            private double avg_;

            public static final Descriptor getDescriptor() {
                return CalculateProto.internal_static_calculate_Result_descriptor;
            }

            protected FieldAccessorTable internalGetFieldAccessorTable() {
                return CalculateProto.internal_static_calculate_Result_fieldAccessorTable.ensureFieldAccessorsInitialized(CalculateProto.Result.class, CalculateProto.Result.Builder.class);
            }

            private Builder() {
                this.maybeForceBuilderInitialization();
            }

            private Builder(BuilderParent parent) {
                super(parent);
                this.maybeForceBuilderInitialization();
            }

            private void maybeForceBuilderInitialization() {
                if (CalculateProto.Result.alwaysUseFieldBuilders) {
                    ;
                }

            }

            public CalculateProto.Result.Builder clear() {
                super.clear();
                this.sum_ = 0;
                this.cnt_ = 0;
                this.avg_ = 0.0D;
                return this;
            }

            public Descriptor getDescriptorForType() {
                return CalculateProto.internal_static_calculate_Result_descriptor;
            }

            public CalculateProto.Result getDefaultInstanceForType() {
                return CalculateProto.Result.DEFAULT_INSTANCE;
            }

            public CalculateProto.Result build() {
                CalculateProto.Result result = this.buildPartial();
                if (!result.isInitialized()) {
                    throw newUninitializedMessageException(result);
                } else {
                    return result;
                }
            }

            public CalculateProto.Result buildPartial() {
                CalculateProto.Result result = new CalculateProto.Result(this, null);
                result.sum_ = this.sum_;
                result.cnt_ = this.cnt_;
                result.avg_ = this.avg_;
                this.onBuilt();
                return result;
            }

            public CalculateProto.Result.Builder clone() {
                return (CalculateProto.Result.Builder)super.clone();
            }

            public CalculateProto.Result.Builder setField(FieldDescriptor field, Object value) {
                return (CalculateProto.Result.Builder)super.setField(field, value);
            }

            public CalculateProto.Result.Builder clearField(FieldDescriptor field) {
                return (CalculateProto.Result.Builder)super.clearField(field);
            }

            public CalculateProto.Result.Builder clearOneof(OneofDescriptor oneof) {
                return (CalculateProto.Result.Builder)super.clearOneof(oneof);
            }

            public CalculateProto.Result.Builder setRepeatedField(FieldDescriptor field, int index, Object value) {
                return (CalculateProto.Result.Builder)super.setRepeatedField(field, index, value);
            }

            public CalculateProto.Result.Builder addRepeatedField(FieldDescriptor field, Object value) {
                return (CalculateProto.Result.Builder)super.addRepeatedField(field, value);
            }

            public CalculateProto.Result.Builder mergeFrom(Message other) {
                if (other instanceof CalculateProto.Result) {
                    return this.mergeFrom((CalculateProto.Result)other);
                } else {
                    super.mergeFrom(other);
                    return this;
                }
            }

            public CalculateProto.Result.Builder mergeFrom(CalculateProto.Result other) {
                if (other == CalculateProto.Result.DEFAULT_INSTANCE) {
                    return this;
                } else {
                    if (other.getSum() != 0) {
                        this.setSum(other.getSum());
                    }

                    if (other.getCnt() != 0) {
                        this.setCnt(other.getCnt());
                    }

                    if (other.getAvg() != 0.0D) {
                        this.setAvg(other.getAvg());
                    }

                    this.mergeUnknownFields(other.unknownFields);
                    this.onChanged();
                    return this;
                }
            }

            public final boolean isInitialized() {
                return true;
            }

            public CalculateProto.Result.Builde