This is an automated email from the ASF dual-hosted git repository.

penghui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 55293017c1a [refactor][function][PIP-166] Function add MANUAL delivery 
semantics (#16279)
55293017c1a is described below

commit 55293017c1a21f10aef9637c9697c7d9fb871fa8
Author: Baodi Shi <[email protected]>
AuthorDate: Mon Aug 1 09:30:36 2022 +0800

    [refactor][function][PIP-166] Function add MANUAL delivery semantics 
(#16279)
---
 .../pulsar/common/functions/FunctionConfig.java    |   5 +-
 .../pulsar/common/functions/WindowConfig.java      |  12 +
 .../org/apache/pulsar/common/io/SinkConfig.java    |   2 +
 pulsar-function-go/conf/conf.go                    |   1 +
 pulsar-function-go/pb/Function.pb.go               | 593 +++++++++++----------
 pulsar-function-go/pb/generate.sh                  |   2 +
 pulsar-function-go/pf/instance.go                  |  17 +-
 pulsar-function-go/pf/instanceConf.go              |  32 +-
 pulsar-function-go/pf/instanceConf_test.go         |  17 +
 pulsar-function-go/pf/instance_test.go             |   8 +-
 pulsar-function-go/pf/stats.go                     |  16 +-
 .../pulsar/functions/instance/ContextImpl.java     |   3 +-
 .../functions/instance/JavaInstanceRunnable.java   |  18 +-
 .../apache/pulsar/functions/sink/PulsarSink.java   |  16 +
 .../functions/source/PulsarFunctionRecord.java     | 113 ++++
 .../windowing/WindowFunctionExecutor.java          |  18 +-
 .../pulsar/functions/windowing/WindowManager.java  |   8 +-
 .../instance/src/main/python/Function_pb2.py       | 123 +++--
 .../instance/src/main/python/python_instance.py    |   3 +-
 .../src/main/python/python_instance_main.py        |  12 +
 .../pulsar/functions/instance/ContextImplTest.java |  13 +-
 .../instance/JavaInstanceRunnableTest.java         |  69 ++-
 .../pulsar/functions/sink/PulsarSinkTest.java      |  46 +-
 .../functions/source/PulsarFunctionRecordTest.java |  62 +++
 .../windowing/WindowFunctionExecutorTest.java      |  44 ++
 .../proto/src/main/proto/Function.proto            |   4 +-
 .../functions/utils/FunctionConfigUtils.java       |  36 +-
 .../pulsar/functions/utils/SinkConfigUtils.java    |   3 +-
 .../pulsar/functions/utils/SourceConfigUtils.java  |   2 +-
 .../functions/utils/FunctionConfigUtilsTest.java   |  17 +
 .../functions/utils/SinkConfigUtilsTest.java       |  14 +
 .../rest/api/v2/FunctionApiV2ResourceTest.java     |   1 +
 .../rest/api/v3/FunctionApiV3ResourceTest.java     |   1 +
 site2/docs/functions-cli.md                        |   4 +-
 site2/docs/functions-concepts.md                   |  13 +-
 35 files changed, 932 insertions(+), 416 deletions(-)

diff --git 
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
 
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
index 527c954110d..dd8a46b7d8b 100644
--- 
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
+++ 
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
@@ -41,7 +41,8 @@ public class FunctionConfig {
     public enum ProcessingGuarantees {
         ATLEAST_ONCE,
         ATMOST_ONCE,
-        EFFECTIVELY_ONCE
+        EFFECTIVELY_ONCE,
+        MANUAL
     }
 
     /**
@@ -102,6 +103,8 @@ public class FunctionConfig {
     // SecretProviderConfigurator.getSecretObjectType() method.
     private Map<String, Object> secrets;
     private Runtime runtime;
+    // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+    @Deprecated
     private Boolean autoAck;
     private Integer maxMessageRetries;
     private String deadLetterTopic;
diff --git 
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
 
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
index 1fb2ef7ca3e..1f507137917 100644
--- 
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
+++ 
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
@@ -47,4 +47,16 @@ public class WindowConfig {
     private String timestampExtractorClassName;
 
     private String actualWindowFunctionClassName;
+
+    private ProcessingGuarantees processingGuarantees;
+
+    /**
+     * This is a semantic option that windows can provide,
+     * forcing the semantics of the {@link 
FunctionConfig.ProcessingGuarantees} to be equal to MANUAL,
+     * and then letting the windows function handle the semantic timing by 
itself.
+     */
+    public enum ProcessingGuarantees {
+        ATLEAST_ONCE,
+        ATMOST_ONCE
+    }
 }
diff --git 
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
 
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
index 5bd9227ca1b..f1844e6090c 100644
--- 
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
+++ 
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
@@ -74,6 +74,8 @@ public class SinkConfig {
     private Boolean retainOrdering;
     private Boolean retainKeyOrdering;
     private Resources resources;
+    // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+    @Deprecated
     private Boolean autoAck;
     private Long timeoutMs;
     private Long negativeAckRedeliveryDelayMs;
diff --git a/pulsar-function-go/conf/conf.go b/pulsar-function-go/conf/conf.go
index dfbf54289f2..c2ff443fcc4 100644
--- a/pulsar-function-go/conf/conf.go
+++ b/pulsar-function-go/conf/conf.go
@@ -49,6 +49,7 @@ type Conf struct {
        ProcessingGuarantees int32  `json:"processingGuarantees" 
yaml:"processingGuarantees"`
        SecretsMap           string `json:"secretsMap" yaml:"secretsMap"`
        Runtime              int32  `json:"runtime" yaml:"runtime"`
+       //Deprecated
        AutoACK              bool   `json:"autoAck" yaml:"autoAck"`
        Parallelism          int32  `json:"parallelism" yaml:"parallelism"`
        //source config
diff --git a/pulsar-function-go/pb/Function.pb.go 
b/pulsar-function-go/pb/Function.pb.go
index d137995dd94..bee1af7cd0c 100644
--- a/pulsar-function-go/pb/Function.pb.go
+++ b/pulsar-function-go/pb/Function.pb.go
@@ -20,7 +20,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 //     protoc-gen-go v1.25.0
-//     protoc        v3.17.3
+//     protoc        v3.19.4
 // source: Function.proto
 
 package api
@@ -50,6 +50,7 @@ const (
        ProcessingGuarantees_ATLEAST_ONCE     ProcessingGuarantees = 0 // 
[default value]
        ProcessingGuarantees_ATMOST_ONCE      ProcessingGuarantees = 1
        ProcessingGuarantees_EFFECTIVELY_ONCE ProcessingGuarantees = 2
+       ProcessingGuarantees_MANUAL           ProcessingGuarantees = 3
 )
 
 // Enum value maps for ProcessingGuarantees.
@@ -58,11 +59,13 @@ var (
                0: "ATLEAST_ONCE",
                1: "ATMOST_ONCE",
                2: "EFFECTIVELY_ONCE",
+               3: "MANUAL",
        }
        ProcessingGuarantees_value = map[string]int32{
                "ATLEAST_ONCE":     0,
                "ATMOST_ONCE":      1,
                "EFFECTIVELY_ONCE": 2,
+               "MANUAL":           3,
        }
 )
 
@@ -510,15 +513,17 @@ type FunctionDetails struct {
        sizeCache     protoimpl.SizeCache
        unknownFields protoimpl.UnknownFields
 
-       Tenant               string                        
`protobuf:"bytes,1,opt,name=tenant,proto3" json:"tenant,omitempty"`
-       Namespace            string                        
`protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"`
-       Name                 string                        
`protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-       ClassName            string                        
`protobuf:"bytes,4,opt,name=className,proto3" json:"className,omitempty"`
-       LogTopic             string                        
`protobuf:"bytes,5,opt,name=logTopic,proto3" json:"logTopic,omitempty"`
-       ProcessingGuarantees ProcessingGuarantees          
`protobuf:"varint,6,opt,name=processingGuarantees,proto3,enum=proto.ProcessingGuarantees"
 json:"processingGuarantees,omitempty"`
-       UserConfig           string                        
`protobuf:"bytes,7,opt,name=userConfig,proto3" json:"userConfig,omitempty"`
-       SecretsMap           string                        
`protobuf:"bytes,16,opt,name=secretsMap,proto3" json:"secretsMap,omitempty"`
-       Runtime              FunctionDetails_Runtime       
`protobuf:"varint,8,opt,name=runtime,proto3,enum=proto.FunctionDetails_Runtime" 
json:"runtime,omitempty"`
+       Tenant               string                  
`protobuf:"bytes,1,opt,name=tenant,proto3" json:"tenant,omitempty"`
+       Namespace            string                  
`protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"`
+       Name                 string                  
`protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
+       ClassName            string                  
`protobuf:"bytes,4,opt,name=className,proto3" json:"className,omitempty"`
+       LogTopic             string                  
`protobuf:"bytes,5,opt,name=logTopic,proto3" json:"logTopic,omitempty"`
+       ProcessingGuarantees ProcessingGuarantees    
`protobuf:"varint,6,opt,name=processingGuarantees,proto3,enum=proto.ProcessingGuarantees"
 json:"processingGuarantees,omitempty"`
+       UserConfig           string                  
`protobuf:"bytes,7,opt,name=userConfig,proto3" json:"userConfig,omitempty"`
+       SecretsMap           string                  
`protobuf:"bytes,16,opt,name=secretsMap,proto3" json:"secretsMap,omitempty"`
+       Runtime              FunctionDetails_Runtime 
`protobuf:"varint,8,opt,name=runtime,proto3,enum=proto.FunctionDetails_Runtime" 
json:"runtime,omitempty"`
+       // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+       //
        AutoAck              bool                          
`protobuf:"varint,9,opt,name=autoAck,proto3" json:"autoAck,omitempty"`
        Parallelism          int32                         
`protobuf:"varint,10,opt,name=parallelism,proto3" json:"parallelism,omitempty"`
        Source               *SourceSpec                   
`protobuf:"bytes,11,opt,name=source,proto3" json:"source,omitempty"`
@@ -632,6 +637,7 @@ func (x *FunctionDetails) GetRuntime() 
FunctionDetails_Runtime {
        return FunctionDetails_JAVA
 }
 
+// Deprecated: Do not use.
 func (x *FunctionDetails) GetAutoAck() bool {
        if x != nil {
                return x.AutoAck
@@ -1660,7 +1666,7 @@ var file_Function_proto_rawDesc = []byte{
        0x61, 0x67, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x28, 
0x0a, 0x0f, 0x64, 0x65,
        0x61, 0x64, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x70, 0x69, 
0x63, 0x18, 0x02, 0x20,
        0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x61, 0x64, 0x4c, 0x65, 0x74, 
0x74, 0x65, 0x72, 0x54,
-       0x6f, 0x70, 0x69, 0x63, 0x22, 0xc5, 0x08, 0x0a, 0x0f, 0x46, 0x75, 0x6e, 
0x63, 0x74, 0x69, 0x6f,
+       0x6f, 0x70, 0x69, 0x63, 0x22, 0xc9, 0x08, 0x0a, 0x0f, 0x46, 0x75, 0x6e, 
0x63, 0x74, 0x69, 0x6f,
        0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 
0x74, 0x65, 0x6e, 0x61,
        0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65, 
0x6e, 0x61, 0x6e, 0x74,
        0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 
0x65, 0x18, 0x02, 0x20,
@@ -1682,294 +1688,295 @@ var file_Function_proto_rawDesc = []byte{
        0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 
0x28, 0x0e, 0x32, 0x1e,
        0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 
0x69, 0x6f, 0x6e, 0x44,
        0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 
0x6d, 0x65, 0x52, 0x07,
-       0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 
0x75, 0x74, 0x6f, 0x41,
-       0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x61, 0x75, 
0x74, 0x6f, 0x41, 0x63,
-       0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 
0x6c, 0x69, 0x73, 0x6d,
-       0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 
0x6c, 0x6c, 0x65, 0x6c,
-       0x69, 0x73, 0x6d, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 
0x65, 0x18, 0x0b, 0x20,
-       0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 
0x53, 0x6f, 0x75, 0x72,
-       0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 
0x63, 0x65, 0x12, 0x23,
-       0x0a, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 
0x32, 0x0f, 0x2e, 0x70,
-       0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 
0x63, 0x52, 0x04, 0x73,
-       0x69, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 
0x72, 0x63, 0x65, 0x73,
-       0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 
0x74, 0x6f, 0x2e, 0x52,
-       0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 
0x73, 0x6f, 0x75, 0x72,
-       0x63, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x63, 0x6b, 0x61, 
0x67, 0x65, 0x55, 0x72,
-       0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x63, 
0x6b, 0x61, 0x67, 0x65,
-       0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x0c, 0x72, 0x65, 0x74, 0x72, 0x79, 
0x44, 0x65, 0x74, 0x61,
-       0x69, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 
0x70, 0x72, 0x6f, 0x74,
-       0x6f, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, 
0x6c, 0x73, 0x52, 0x0c,
-       0x72, 0x65, 0x74, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 
0x12, 0x22, 0x0a, 0x0c,
-       0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 
0x18, 0x11, 0x20, 0x01,
-       0x28, 0x09, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46, 
0x6c, 0x61, 0x67, 0x73,
-       0x12, 0x4a, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 
0x74, 0x54, 0x79, 0x70,
-       0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x70, 0x72, 
0x6f, 0x74, 0x6f, 0x2e,
-       0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 
0x69, 0x6c, 0x73, 0x2e,
-       0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 
0x65, 0x52, 0x0d, 0x63,
-       0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 
0x12, 0x32, 0x0a, 0x14,
+       0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x61, 
0x75, 0x74, 0x6f, 0x41,
+       0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 
0x52, 0x07, 0x61, 0x75,
+       0x74, 0x6f, 0x41, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 
0x61, 0x6c, 0x6c, 0x65,
+       0x6c, 0x69, 0x73, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 
0x70, 0x61, 0x72, 0x61,
+       0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x12, 0x29, 0x0a, 0x06, 0x73, 
0x6f, 0x75, 0x72, 0x63,
+       0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 
0x6f, 0x74, 0x6f, 0x2e,
+       0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 
0x73, 0x6f, 0x75, 0x72,
+       0x63, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x18, 0x0c, 
0x20, 0x01, 0x28, 0x0b,
+       0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 
0x6b, 0x53, 0x70, 0x65,
+       0x63, 0x52, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x09, 0x72, 
0x65, 0x73, 0x6f, 0x75,
+       0x72, 0x63, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 
0x2e, 0x70, 0x72, 0x6f,
+       0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 
0x52, 0x09, 0x72, 0x65,
+       0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 
0x61, 0x63, 0x6b, 0x61,
+       0x67, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 
0x0a, 0x70, 0x61, 0x63,
+       0x6b, 0x61, 0x67, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x0c, 0x72, 
0x65, 0x74, 0x72, 0x79,
+       0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 
0x0b, 0x32, 0x13, 0x2e,
+       0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x44, 
0x65, 0x74, 0x61, 0x69,
+       0x6c, 0x73, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x72, 0x79, 0x44, 0x65, 0x74, 
0x61, 0x69, 0x6c, 0x73,
+       0x12, 0x22, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46, 
0x6c, 0x61, 0x67, 0x73,
+       0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x74, 
0x69, 0x6d, 0x65, 0x46,
+       0x6c, 0x61, 0x67, 0x73, 0x12, 0x4a, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 
0x6f, 0x6e, 0x65, 0x6e,
+       0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0e, 0x32, 
0x24, 0x2e, 0x70, 0x72,
+       0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
0x44, 0x65, 0x74, 0x61,
+       0x69, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 
0x74, 0x54, 0x79, 0x70,
+       0x65, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 
0x54, 0x79, 0x70, 0x65,
+       0x12, 0x32, 0x0a, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 
0x6e, 0x74, 0x69, 0x6d,
+       0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x13, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x14,
        0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 
0x65, 0x4f, 0x70, 0x74,
-       0x69, 0x6f, 0x6e, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 
0x63, 0x75, 0x73, 0x74,
-       0x6f, 0x6d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x70, 0x74, 
0x69, 0x6f, 0x6e, 0x73,
-       0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x18, 
0x14, 0x20, 0x01, 0x28,
-       0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x12, 0x26, 
0x0a, 0x0e, 0x72, 0x65,
-       0x74, 0x61, 0x69, 0x6e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 
0x18, 0x15, 0x20, 0x01,
-       0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4f, 0x72, 
0x64, 0x65, 0x72, 0x69,
-       0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 
0x4b, 0x65, 0x79, 0x4f,
-       0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x16, 0x20, 0x01, 0x28, 
0x08, 0x52, 0x11, 0x72,
-       0x65, 0x74, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x72, 0x64, 0x65, 
0x72, 0x69, 0x6e, 0x67,
-       0x12, 0x4f, 0x0a, 0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 
0x74, 0x69, 0x6f, 0x6e,
-       0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x01, 
0x28, 0x0e, 0x32, 0x1b,
-       0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 
0x72, 0x69, 0x70, 0x74,
-       0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 
0x14, 0x73, 0x75, 0x62,
-       0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 
0x69, 0x74, 0x69, 0x6f,
-       0x6e, 0x22, 0x27, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 
0x12, 0x08, 0x0a, 0x04,
-       0x4a, 0x41, 0x56, 0x41, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x59, 
0x54, 0x48, 0x4f, 0x4e,
-       0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x4f, 0x10, 0x03, 0x22, 0x40, 
0x0a, 0x0d, 0x43, 0x6f,
-       0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 
0x0b, 0x0a, 0x07, 0x55,
-       0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 
0x46, 0x55, 0x4e, 0x43,
-       0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x4f, 
0x55, 0x52, 0x43, 0x45,
-       0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x49, 0x4e, 0x4b, 0x10, 0x03, 
0x22, 0x95, 0x05, 0x0a,
-       0x0c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65, 
0x63, 0x12, 0x1e, 0x0a,
-       0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 
0x01, 0x20, 0x01, 0x28,
-       0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 
0x65, 0x12, 0x26, 0x0a,
-       0x0e, 0x73, 0x65, 0x72, 0x64, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 
0x61, 0x6d, 0x65, 0x18,
-       0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x64, 0x65, 
0x43, 0x6c, 0x61, 0x73,
-       0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x73, 0x52, 
0x65, 0x67, 0x65, 0x78,
-       0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 
0x08, 0x52, 0x0e, 0x69,
-       0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 
0x6e, 0x12, 0x53, 0x0a,
-       0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65, 
0x75, 0x65, 0x53, 0x69,
-       0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 
0x72, 0x6f, 0x74, 0x6f,
-       0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65, 
0x63, 0x2e, 0x52, 0x65,
-       0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65, 0x75, 0x65, 0x53, 
0x69, 0x7a, 0x65, 0x52,
-       0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65, 
0x75, 0x65, 0x53, 0x69,
-       0x7a, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 
0x50, 0x72, 0x6f, 0x70,
-       0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 
0x32, 0x29, 0x2e, 0x70,
+       0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 
0x74, 0x69, 0x6e, 0x18,
+       0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 
0x69, 0x6e, 0x12, 0x26,
+       0x0a, 0x0e, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4f, 0x72, 0x64, 0x65, 
0x72, 0x69, 0x6e, 0x67,
+       0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, 0x61, 
0x69, 0x6e, 0x4f, 0x72,
+       0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x65, 
0x74, 0x61, 0x69, 0x6e,
+       0x4b, 0x65, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 
0x16, 0x20, 0x01, 0x28,
+       0x08, 0x52, 0x11, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 
0x4f, 0x72, 0x64, 0x65,
+       0x72, 0x69, 0x6e, 0x67, 0x12, 0x4f, 0x0a, 0x14, 0x73, 0x75, 0x62, 0x73, 
0x63, 0x72, 0x69, 0x70,
+       0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 
0x18, 0x17, 0x20, 0x01,
+       0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 
0x75, 0x62, 0x73, 0x63,
+       0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 
0x69, 0x6f, 0x6e, 0x52,
+       0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 
0x6e, 0x50, 0x6f, 0x73,
+       0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x0a, 0x07, 0x52, 0x75, 0x6e, 
0x74, 0x69, 0x6d, 0x65,
+       0x12, 0x08, 0x0a, 0x04, 0x4a, 0x41, 0x56, 0x41, 0x10, 0x00, 0x12, 0x0a, 
0x0a, 0x06, 0x50, 0x59,
+       0x54, 0x48, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x4f, 
0x10, 0x03, 0x22, 0x40,
+       0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 
0x79, 0x70, 0x65, 0x12,
+       0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 
0x12, 0x0c, 0x0a, 0x08,
+       0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0a, 
0x0a, 0x06, 0x53, 0x4f,
+       0x55, 0x52, 0x43, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x49, 
0x4e, 0x4b, 0x10, 0x03,
+       0x22, 0x95, 0x05, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 
0x72, 0x53, 0x70, 0x65,
+       0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 
0x79, 0x70, 0x65, 0x18,
+       0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 
0x61, 0x54, 0x79, 0x70,
+       0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x64, 0x65, 0x43, 0x6c, 
0x61, 0x73, 0x73, 0x4e,
+       0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 
0x65, 0x72, 0x64, 0x65,
+       0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 
0x0e, 0x69, 0x73, 0x52,
+       0x65, 0x67, 0x65, 0x78, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 
0x03, 0x20, 0x01, 0x28,
+       0x08, 0x52, 0x0e, 0x69, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x50, 0x61, 
0x74, 0x74, 0x65, 0x72,
+       0x6e, 0x12, 0x53, 0x0a, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 
0x72, 0x51, 0x75, 0x65,
+       0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 
0x32, 0x25, 0x2e, 0x70,
        0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 
0x72, 0x53, 0x70, 0x65,
-       0x63, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 
0x65, 0x72, 0x74, 0x69,
-       0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x73, 0x63, 0x68, 
0x65, 0x6d, 0x61, 0x50,
-       0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x5b, 0x0a, 
0x12, 0x63, 0x6f, 0x6e,
-       0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
0x69, 0x65, 0x73, 0x18,
-       0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 
0x6f, 0x2e, 0x43, 0x6f,
-       0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x43, 
0x6f, 0x6e, 0x73, 0x75,
-       0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 
0x73, 0x45, 0x6e, 0x74,
-       0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 
0x50, 0x72, 0x6f, 0x70,
-       0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x72, 
0x79, 0x70, 0x74, 0x6f,
-       0x53, 0x70, 0x65, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 
0x2e, 0x70, 0x72, 0x6f,
-       0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 
0x63, 0x52, 0x0a, 0x63,
-       0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x22, 0x0a, 
0x0c, 0x70, 0x6f, 0x6f,
-       0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x08, 0x20, 
0x01, 0x28, 0x08, 0x52,
-       0x0c, 0x70, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 
0x73, 0x1a, 0x29, 0x0a,
-       0x11, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65, 
0x75, 0x65, 0x53, 0x69,
-       0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 
0x01, 0x20, 0x01, 0x28,
-       0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x43, 0x0a, 0x15, 
0x53, 0x63, 0x68, 0x65,
-       0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 
0x45, 0x6e, 0x74, 0x72,
-       0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x03,
-       0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 
0x18, 0x02, 0x20, 0x01,
-       0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 
0x01, 0x1a, 0x45, 0x0a,
-       0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 
0x70, 0x65, 0x72, 0x74,
-       0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 
0x6b, 0x65, 0x79, 0x18,
-       0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 
0x0a, 0x05, 0x76, 0x61,
-       0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 
0x61, 0x6c, 0x75, 0x65,
-       0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x02, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 
0x64, 0x75, 0x63, 0x65,
-       0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x12, 0x6d, 0x61, 0x78, 
0x50, 0x65, 0x6e, 0x64,
-       0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 
0x01, 0x20, 0x01, 0x28,
-       0x05, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 
0x67, 0x4d, 0x65, 0x73,
-       0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x22, 0x6d, 0x61, 0x78, 
0x50, 0x65, 0x6e, 0x64,
-       0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x41, 
0x63, 0x72, 0x6f, 0x73,
-       0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 
0x02, 0x20, 0x01, 0x28,
-       0x05, 0x52, 0x22, 0x6d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 
0x67, 0x4d, 0x65, 0x73,
-       0x73, 0x61, 0x67, 0x65, 0x73, 0x41, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x50, 
0x61, 0x72, 0x74, 0x69,
-       0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x75, 0x73, 0x65, 
0x54, 0x68, 0x72, 0x65,
-       0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x64, 0x75, 
0x63, 0x65, 0x72, 0x73,
-       0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x75, 0x73, 0x65, 0x54, 
0x68, 0x72, 0x65, 0x61,
-       0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 
0x65, 0x72, 0x73, 0x12,
-       0x31, 0x0a, 0x0a, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 
0x63, 0x18, 0x04, 0x20,
-       0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 
0x43, 0x72, 0x79, 0x70,
-       0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x72, 0x79, 0x70, 
0x74, 0x6f, 0x53, 0x70,
-       0x65, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, 0x74, 0x63, 0x68, 0x42, 
0x75, 0x69, 0x6c, 0x64,
-       0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 
0x74, 0x63, 0x68, 0x42,
-       0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xc1, 0x03, 0x0a, 0x0a, 0x43, 
0x72, 0x79, 0x70, 0x74,
-       0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x18, 0x63, 0x72, 0x79, 
0x70, 0x74, 0x6f, 0x4b,
-       0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 
0x73, 0x4e, 0x61, 0x6d,
-       0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x63, 0x72, 0x79, 
0x70, 0x74, 0x6f, 0x4b,
-       0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 
0x73, 0x4e, 0x61, 0x6d,
-       0x65, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x4b, 
0x65, 0x79, 0x52, 0x65,
-       0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 
0x20, 0x01, 0x28, 0x09,
-       0x52, 0x15, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x52, 
0x65, 0x61, 0x64, 0x65,
-       0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x19, 0x70, 
0x72, 0x6f, 0x64, 0x75,
-       0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 
0x6e, 0x4b, 0x65, 0x79,
-       0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 
0x70, 0x72, 0x6f, 0x64,
-       0x75, 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 
0x6f, 0x6e, 0x4b, 0x65,
-       0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x61, 0x0a, 0x1b, 0x70, 0x72, 0x6f, 
0x64, 0x75, 0x63, 0x65,
-       0x72, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x75, 
0x72, 0x65, 0x41, 0x63,
-       0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 
0x2e, 0x70, 0x72, 0x6f,
-       0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 
0x63, 0x2e, 0x46, 0x61,
-       0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 
0x1b, 0x70, 0x72, 0x6f,
+       0x63, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 
0x65, 0x75, 0x65, 0x53,
+       0x69, 0x7a, 0x65, 0x52, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 
0x72, 0x51, 0x75, 0x65,
+       0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x73, 0x63, 
0x68, 0x65, 0x6d, 0x61,
+       0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 
0x20, 0x03, 0x28, 0x0b,
+       0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 
0x73, 0x75, 0x6d, 0x65,
+       0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 
0x50, 0x72, 0x6f, 0x70,
+       0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 
0x10, 0x73, 0x63, 0x68,
+       0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 
0x73, 0x12, 0x5b, 0x0a,
+       0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 
0x70, 0x65, 0x72, 0x74,
+       0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 
0x70, 0x72, 0x6f, 0x74,
+       0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 
0x65, 0x63, 0x2e, 0x43,
+       0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 
0x72, 0x74, 0x69, 0x65,
+       0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 
0x75, 0x6d, 0x65, 0x72,
+       0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31, 
0x0a, 0x0a, 0x63, 0x72,
+       0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x18, 0x07, 0x20, 0x01, 
0x28, 0x0b, 0x32, 0x11,
+       0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 
0x6f, 0x53, 0x70, 0x65,
+       0x63, 0x52, 0x0a, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 
0x63, 0x12, 0x22, 0x0a,
+       0x0c, 0x70, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 
0x73, 0x18, 0x08, 0x20,
+       0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 
0x73, 0x61, 0x67, 0x65,
+       0x73, 0x1a, 0x29, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 
0x72, 0x51, 0x75, 0x65,
+       0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 
0x6c, 0x75, 0x65, 0x18,
+       0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 
0x1a, 0x43, 0x0a, 0x15,
+       0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 
0x74, 0x69, 0x65, 0x73,
+       0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 
0x18, 0x01, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 
0x61, 0x6c, 0x75, 0x65,
+       0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 
0x65, 0x3a, 0x02, 0x38,
+       0x01, 0x1a, 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 
0x72, 0x50, 0x72, 0x6f,
+       0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 
0x12, 0x10, 0x0a, 0x03,
+       0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 
0x65, 0x79, 0x12, 0x14,
+       0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 
0x09, 0x52, 0x05, 0x76,
+       0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x02, 0x0a, 
0x0c, 0x50, 0x72, 0x6f,
+       0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 
0x12, 0x6d, 0x61, 0x78,
+       0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 
0x67, 0x65, 0x73, 0x18,
+       0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65, 
0x6e, 0x64, 0x69, 0x6e,
+       0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x4e, 0x0a, 
0x22, 0x6d, 0x61, 0x78,
+       0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 
0x67, 0x65, 0x73, 0x41,
+       0x63, 0x72, 0x6f, 0x73, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 
0x6f, 0x6e, 0x73, 0x18,
+       0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x22, 0x6d, 0x61, 0x78, 0x50, 0x65, 
0x6e, 0x64, 0x69, 0x6e,
+       0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x41, 0x63, 0x72, 
0x6f, 0x73, 0x73, 0x50,
+       0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 
0x17, 0x75, 0x73, 0x65,
+       0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 
0x72, 0x6f, 0x64, 0x75,
+       0x63, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 
0x75, 0x73, 0x65, 0x54,
+       0x68, 0x72, 0x65, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 
0x6f, 0x64, 0x75, 0x63,
+       0x65, 0x72, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x72, 0x79, 0x70, 0x74, 
0x6f, 0x53, 0x70, 0x65,
+       0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 
0x6f, 0x74, 0x6f, 0x2e,
+       0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 
0x63, 0x72, 0x79, 0x70,
+       0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, 
0x74, 0x63, 0x68, 0x42,
+       0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x0c, 0x62, 0x61,
+       0x74, 0x63, 0x68, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xc1, 
0x03, 0x0a, 0x0a, 0x43,
+       0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3a, 0x0a, 
0x18, 0x63, 0x72, 0x79,
+       0x70, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 
0x43, 0x6c, 0x61, 0x73,
+       0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 
0x18, 0x63, 0x72, 0x79,
+       0x70, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 
0x43, 0x6c, 0x61, 0x73,
+       0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x72, 0x79, 
0x70, 0x74, 0x6f, 0x4b,
+       0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 
0x69, 0x67, 0x18, 0x02,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 
0x4b, 0x65, 0x79, 0x52,
+       0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 
0x3c, 0x0a, 0x19, 0x70,
+       0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79, 
0x70, 0x74, 0x69, 0x6f,
+       0x6e, 0x4b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x03, 
0x28, 0x09, 0x52, 0x19,
+       0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 
0x79, 0x70, 0x74, 0x69,
+       0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x61, 0x0a, 
0x1b, 0x70, 0x72, 0x6f,
        0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x46, 
0x61, 0x69, 0x6c, 0x75,
-       0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x61, 0x0a, 0x1b, 
0x63, 0x6f, 0x6e, 0x73,
-       0x75, 0x6d, 0x65, 0x72, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x46, 0x61, 
0x69, 0x6c, 0x75, 0x72,
-       0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 
0x0e, 0x32, 0x1f, 0x2e,
-       0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 
0x53, 0x70, 0x65, 0x63,
-       0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 
0x6f, 0x6e, 0x52, 0x1b,
+       0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 
0x28, 0x0e, 0x32, 0x1f,
+       0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 
0x6f, 0x53, 0x70, 0x65,
+       0x63, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 
0x69, 0x6f, 0x6e, 0x52,
+       0x1b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x72, 0x79, 
0x70, 0x74, 0x6f, 0x46,
+       0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
0x12, 0x61, 0x0a, 0x1b,
        0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x43, 0x72, 0x79, 0x70, 
0x74, 0x6f, 0x46, 0x61,
-       0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 
0x3d, 0x0a, 0x0d, 0x46,
-       0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
0x12, 0x08, 0x0a, 0x04,
-       0x46, 0x41, 0x49, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49, 
0x53, 0x43, 0x41, 0x52,
-       0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x53, 0x55, 
0x4d, 0x45, 0x10, 0x02,
-       0x12, 0x08, 0x0a, 0x04, 0x53, 0x45, 0x4e, 0x44, 0x10, 0x0a, 0x22, 0xd1, 
0x06, 0x0a, 0x0a, 0x53,
-       0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1c, 0x0a, 
0x09, 0x63, 0x6c, 0x61,
-       0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x09, 0x63, 0x6c,
-       0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 
0x6f, 0x6e, 0x66, 0x69,
-       0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 
0x6e, 0x66, 0x69, 0x67,
-       0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x79, 0x70, 0x65, 0x43, 0x6c, 0x61, 
0x73, 0x73, 0x4e, 0x61,
-       0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x79, 
0x70, 0x65, 0x43, 0x6c,
-       0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x73, 
0x75, 0x62, 0x73, 0x63,
-       0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 
0x03, 0x20, 0x01, 0x28,
-       0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x75, 
0x62, 0x73, 0x63, 0x72,
-       0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10, 
0x73, 0x75, 0x62, 0x73,
-       0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 
0x12, 0x69, 0x0a, 0x16,
-       0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x44, 
0x65, 0x43, 0x6c, 0x61,
-       0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 
0x32, 0x2d, 0x2e, 0x70,
-       0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 
0x70, 0x65, 0x63, 0x2e,
-       0x54, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x44, 
0x65, 0x43, 0x6c, 0x61,
-       0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 
0x02, 0x18, 0x01, 0x52,
-       0x16, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x72, 
0x44, 0x65, 0x43, 0x6c,
-       0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x69, 
0x6e, 0x70, 0x75, 0x74,
-       0x53, 0x70, 0x65, 0x63, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 
0x21, 0x2e, 0x70, 0x72,
-       0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 
0x65, 0x63, 0x2e, 0x49,
-       0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x45, 0x6e, 0x74, 
0x72, 0x79, 0x52, 0x0a,
-       0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x12, 0x1c, 
0x0a, 0x09, 0x74, 0x69,
-       0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 
0x04, 0x52, 0x09, 0x74,
-       0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x0d, 
0x74, 0x6f, 0x70, 0x69,
-       0x63, 0x73, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x07, 0x20, 
0x01, 0x28, 0x09, 0x42,
-       0x02, 0x18, 0x01, 0x52, 0x0d, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x50, 
0x61, 0x74, 0x74, 0x65,
-       0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 
0x6e, 0x18, 0x08, 0x20,
-       0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 
0x12, 0x2a, 0x0a, 0x10,
-       0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 
0x4e, 0x61, 0x6d, 0x65,
-       0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x62, 0x73, 
0x63, 0x72, 0x69, 0x70,
-       0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 
0x63, 0x6c, 0x65, 0x61,
-       0x6e, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 
0x69, 0x6f, 0x6e, 0x18,
-       0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x63, 0x6c, 0x65, 0x61, 0x6e, 
0x75, 0x70, 0x53, 0x75,
-       0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4f, 
0x0a, 0x14, 0x73, 0x75,
-       0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 
0x73, 0x69, 0x74, 0x69,
-       0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 
0x72, 0x6f, 0x74, 0x6f,
-       0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 
0x6e, 0x50, 0x6f, 0x73,
-       0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 
0x72, 0x69, 0x70, 0x74,
-       0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 
0x42, 0x0a, 0x1c, 0x6e,
-       0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x6b, 0x52, 0x65, 
0x64, 0x65, 0x6c, 0x69,
-       0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x18, 
0x0d, 0x20, 0x01, 0x28,
-       0x04, 0x52, 0x1c, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41, 
0x63, 0x6b, 0x52, 0x65,
-       0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x61, 
0x79, 0x4d, 0x73, 0x1a,
-       0x49, 0x0a, 0x1b, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 
0x65, 0x72, 0x44, 0x65,
-       0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 
0x72, 0x79, 0x12, 0x10,
+       0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 
0x05, 0x20, 0x01, 0x28,
+       0x0e, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 
0x79, 0x70, 0x74, 0x6f,
+       0x53, 0x70, 0x65, 0x63, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 
0x41, 0x63, 0x74, 0x69,
+       0x6f, 0x6e, 0x52, 0x1b, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 
0x43, 0x72, 0x79, 0x70,
+       0x74, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 
0x69, 0x6f, 0x6e, 0x22,
+       0x3d, 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 
0x74, 0x69, 0x6f, 0x6e,
+       0x12, 0x08, 0x0a, 0x04, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x00, 0x12, 0x0b, 
0x0a, 0x07, 0x44, 0x49,
+       0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 
0x4f, 0x4e, 0x53, 0x55,
+       0x4d, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x45, 0x4e, 0x44, 
0x10, 0x0a, 0x22, 0xd1,
+       0x06, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 
0x63, 0x12, 0x1c, 0x0a,
+       0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 
0x20, 0x01, 0x28, 0x09,
+       0x52, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 
0x18, 0x0a, 0x07, 0x63,
+       0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x07, 0x63, 0x6f,
+       0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x79, 0x70, 
0x65, 0x43, 0x6c, 0x61,
+       0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x0d, 0x74, 0x79,
+       0x70, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 
0x43, 0x0a, 0x10, 0x73,
+       0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 
0x79, 0x70, 0x65, 0x18,
+       0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 
0x6f, 0x2e, 0x53, 0x75,
+       0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 
0x70, 0x65, 0x52, 0x10,
+       0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 
0x54, 0x79, 0x70, 0x65,
+       0x12, 0x69, 0x0a, 0x16, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 
0x53, 0x65, 0x72, 0x44,
+       0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 
0x20, 0x03, 0x28, 0x0b,
+       0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 
0x72, 0x63, 0x65, 0x53,
+       0x70, 0x65, 0x63, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 
0x53, 0x65, 0x72, 0x44,
+       0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 
0x74, 0x72, 0x79, 0x42,
+       0x02, 0x18, 0x01, 0x52, 0x16, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 
0x6f, 0x53, 0x65, 0x72,
+       0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 
0x41, 0x0a, 0x0a, 0x69,
+       0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x18, 0x0a, 0x20, 
0x03, 0x28, 0x0b, 0x32,
+       0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 
0x63, 0x65, 0x53, 0x70,
+       0x65, 0x63, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 
0x73, 0x45, 0x6e, 0x74,
+       0x72, 0x79, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 
0x63, 0x73, 0x12, 0x1c,
+       0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 
0x06, 0x20, 0x01, 0x28,
+       0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 
0x12, 0x28, 0x0a, 0x0d,
+       0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 
0x6e, 0x18, 0x07, 0x20,
+       0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x74, 0x6f, 0x70, 
0x69, 0x63, 0x73, 0x50,
+       0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 
0x69, 0x6c, 0x74, 0x69,
+       0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 
0x6c, 0x74, 0x69, 0x6e,
+       0x12, 0x2a, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 
0x74, 0x69, 0x6f, 0x6e,
+       0x4e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 
0x73, 0x75, 0x62, 0x73,
+       0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 
0x12, 0x30, 0x0a, 0x13,
+       0x63, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 
0x72, 0x69, 0x70, 0x74,
+       0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x63, 
0x6c, 0x65, 0x61, 0x6e,
+       0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 
0x6f, 0x6e, 0x12, 0x4f,
+       0x0a, 0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 
0x6f, 0x6e, 0x50, 0x6f,
+       0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 
0x32, 0x1b, 0x2e, 0x70,
+       0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 
0x70, 0x74, 0x69, 0x6f,
+       0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x73, 
0x75, 0x62, 0x73, 0x63,
+       0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 
0x69, 0x6f, 0x6e, 0x12,
+       0x42, 0x0a, 0x1c, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41, 
0x63, 0x6b, 0x52, 0x65,
+       0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x61, 
0x79, 0x4d, 0x73, 0x18,
+       0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x65, 0x67, 0x61, 0x74, 
0x69, 0x76, 0x65, 0x41,
+       0x63, 0x6b, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 
0x44, 0x65, 0x6c, 0x61,
+       0x79, 0x4d, 0x73, 0x1a, 0x49, 0x0a, 0x1b, 0x54, 0x6f, 0x70, 0x69, 0x63, 
0x73, 0x54, 0x6f, 0x53,
+       0x65, 0x72, 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 
0x65, 0x45, 0x6e, 0x74,
+       0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 
0x65, 0x18, 0x02, 0x20,
+       0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 
0x38, 0x01, 0x1a, 0x52,
+       0x0a, 0x0f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 
0x45, 0x6e, 0x74, 0x72,
+       0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x03,
+       0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 
0x18, 0x02, 0x20, 0x01,
+       0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 
0x6f, 0x6e, 0x73, 0x75,
+       0x6d, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 
0x75, 0x65, 0x3a, 0x02,
+       0x38, 0x01, 0x22, 0x95, 0x05, 0x0a, 0x08, 0x53, 0x69, 0x6e, 0x6b, 0x53, 
0x70, 0x65, 0x63, 0x12,
+       0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 
0x18, 0x01, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 
0x65, 0x12, 0x18, 0x0a,
+       0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x07,
+       0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 
0x79, 0x70, 0x65, 0x43,
+       0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x0d,
+       0x74, 0x79, 0x70, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 
0x65, 0x12, 0x14, 0x0a,
+       0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x05, 0x74, 0x6f,
+       0x70, 0x69, 0x63, 0x12, 0x37, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 
0x63, 0x65, 0x72, 0x53,
+       0x70, 0x65, 0x63, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 
0x70, 0x72, 0x6f, 0x74,
+       0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 
0x65, 0x63, 0x52, 0x0c,
+       0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 
0x12, 0x26, 0x0a, 0x0e,
+       0x73, 0x65, 0x72, 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 
0x6d, 0x65, 0x18, 0x04,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x44, 0x65, 0x43, 
0x6c, 0x61, 0x73, 0x73,
+       0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 
0x74, 0x69, 0x6e, 0x18,
+       0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 
0x69, 0x6e, 0x12, 0x1e,
+       0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 
0x18, 0x07, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 
0x70, 0x65, 0x12, 0x42,
+       0x0a, 0x1c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x6f, 0x75, 
0x72, 0x63, 0x65, 0x4d,
+       0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 
0x74, 0x79, 0x18, 0x08,
+       0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 
0x64, 0x53, 0x6f, 0x75,
+       0x72, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 
0x6f, 0x70, 0x65, 0x72,
+       0x74, 0x79, 0x12, 0x51, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 
0x50, 0x72, 0x6f, 0x70,
+       0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 
0x32, 0x25, 0x2e, 0x70,
+       0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 
0x63, 0x2e, 0x53, 0x63,
+       0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 
0x65, 0x73, 0x45, 0x6e,
+       0x74, 0x72, 0x79, 0x52, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 
0x72, 0x6f, 0x70, 0x65,
+       0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 
0x73, 0x75, 0x6d, 0x65,
+       0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 
0x0a, 0x20, 0x03, 0x28,
+       0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 
0x6e, 0x6b, 0x53, 0x70,
+       0x65, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 
0x72, 0x6f, 0x70, 0x65,
+       0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 
0x63, 0x6f, 0x6e, 0x73,
+       0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 
0x65, 0x73, 0x1a, 0x43,
+       0x0a, 0x15, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 
0x65, 0x72, 0x74, 0x69,
+       0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 
0x65, 0x79, 0x18, 0x01,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 
0x05, 0x76, 0x61, 0x6c,
+       0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 
0x6c, 0x75, 0x65, 0x3a,
+       0x02, 0x38, 0x01, 0x1a, 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 
0x6d, 0x65, 0x72, 0x50,
+       0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 
0x72, 0x79, 0x12, 0x10,
        0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 
0x03, 0x6b, 0x65, 0x79,
        0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x09, 0x52,
-       0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x52, 
0x0a, 0x0f, 0x49, 0x6e,
-       0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 
0x79, 0x12, 0x10, 0x0a,
-       0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 
0x6b, 0x65, 0x79, 0x12,
-       0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 
0x28, 0x0b, 0x32, 0x13,
-       0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 
0x6d, 0x65, 0x72, 0x53,
-       0x70, 0x65, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 
0x38, 0x01, 0x22, 0x95,
-       0x05, 0x0a, 0x08, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x12, 
0x1c, 0x0a, 0x09, 0x63,
-       0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x09,
-       0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 
0x07, 0x63, 0x6f, 0x6e,
-       0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 
0x63, 0x6f, 0x6e, 0x66,
-       0x69, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x79, 0x70, 0x65, 0x43, 
0x6c, 0x61, 0x73, 0x73,
-       0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 
0x74, 0x79, 0x70, 0x65,
-       0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 
0x05, 0x74, 0x6f, 0x70,
-       0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 
0x70, 0x69, 0x63, 0x12,
-       0x37, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 
0x70, 0x65, 0x63, 0x18,
-       0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 
0x6f, 0x2e, 0x50, 0x72,
-       0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 
0x70, 0x72, 0x6f, 0x64,
-       0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x26, 0x0a, 0x0e, 
0x73, 0x65, 0x72, 0x44,
-       0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 
0x20, 0x01, 0x28, 0x09,
-       0x52, 0x0e, 0x73, 0x65, 0x72, 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 
0x4e, 0x61, 0x6d, 0x65,
-       0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x18, 
0x06, 0x20, 0x01, 0x28,
-       0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x12, 0x1e, 
0x0a, 0x0a, 0x73, 0x63,
-       0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x0a,
-       0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x42, 
0x0a, 0x1c, 0x66, 0x6f,
-       0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 
0x65, 0x73, 0x73, 0x61,
-       0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x08, 
0x20, 0x01, 0x28, 0x08,
-       0x52, 0x1c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x6f, 0x75, 
0x72, 0x63, 0x65, 0x4d,
-       0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 
0x74, 0x79, 0x12, 0x51,
-       0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 
0x65, 0x72, 0x74, 0x69,
-       0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 
0x72, 0x6f, 0x74, 0x6f,
-       0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x53, 0x63, 
0x68, 0x65, 0x6d, 0x61,
-       0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 
0x74, 0x72, 0x79, 0x52,
-       0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 
0x72, 0x74, 0x69, 0x65,
-       0x73, 0x12, 0x57, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 
0x72, 0x50, 0x72, 0x6f,
-       0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 
0x0b, 0x32, 0x27, 0x2e,
-       0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 
0x65, 0x63, 0x2e, 0x43,
-       0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 
0x72, 0x74, 0x69, 0x65,
-       0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 
0x75, 0x6d, 0x65, 0x72,
-       0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x43, 
0x0a, 0x15, 0x53, 0x63,
-       0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 
0x65, 0x73, 0x45, 0x6e,
-       0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 
0x20, 0x01, 0x28, 0x09,
-       0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 
0x75, 0x65, 0x18, 0x02,
-       0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 
0x02, 0x38, 0x01, 0x1a,
-       0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 
0x72, 0x6f, 0x70, 0x65,
-       0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 
0x0a, 0x03, 0x6b, 0x65,
-       0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 
0x12, 0x14, 0x0a, 0x05,
-       0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 
0x05, 0x76, 0x61, 0x6c,
-       0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x67, 0x0a, 0x17, 0x50, 0x61, 
0x63, 0x6b, 0x61, 0x67,
-       0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 
0x61, 0x44, 0x61, 0x74,
-       0x61, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 
0x50, 0x61, 0x74, 0x68,
-       0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 
0x61, 0x67, 0x65, 0x50,
-       0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 
0x6e, 0x61, 0x6c, 0x46,
-       0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 
0x09, 0x52, 0x10, 0x6f,
-       0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x4e, 
0x61, 0x6d, 0x65, 0x22,
-       0xd5, 0x03, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
0x4d, 0x65, 0x74, 0x61,
-       0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0f, 0x66, 0x75, 0x6e, 0x63, 
0x74, 0x69, 0x6f, 0x6e,
-       0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 
0x0b, 0x32, 0x16, 0x2e,
-       0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 
0x6f, 0x6e, 0x44, 0x65,
-       0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x66, 0x75, 0x6e, 0x63, 0x74, 
0x69, 0x6f, 0x6e, 0x44,
-       0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x48, 0x0a, 0x0f, 0x70, 0x61, 
0x63, 0x6b, 0x61, 0x67,
-       0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x0b, 0x32,
-       0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x63, 0x6b, 
0x61, 0x67, 0x65, 0x4c,
-       0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 
0x61, 0x74, 0x61, 0x52,
-       0x0f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 
0x74, 0x69, 0x6f, 0x6e,
-       0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 
0x03, 0x20, 0x01, 0x28,
-       0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 
0x0a, 0x0a, 0x63, 0x72,
-       0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 
0x28, 0x04, 0x52, 0x0a,
-       0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x53, 
0x0a, 0x0e, 0x69, 0x6e,
-       0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 
0x18, 0x05, 0x20, 0x03,
-       0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 
0x75, 0x6e, 0x63, 0x74,
-       0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x2e, 
0x49, 0x6e, 0x73, 0x74,
-       0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 
0x74, 0x72, 0x79, 0x52,
-       0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 
0x74, 0x65, 0x73, 0x12,
-       0x4d, 0x0a, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 
0x75, 0x74, 0x68, 0x53,
-       0x70, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 
0x70, 0x72, 0x6f, 0x74,
-       0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 
0x74, 0x68, 0x65, 0x6e,
-       0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 
0x52, 0x10, 0x66, 0x75,
-       0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x53, 0x70, 
0x65, 0x63, 0x1a, 0x57,
-       0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 
0x61, 0x74, 0x65, 0x73,
-       0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 
0x18, 0x01, 0x20, 0x01,
-       0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 
0x61, 0x6c, 0x75, 0x65,
-       0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 
0x74, 0x6f, 0x2e, 0x46,
-       0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 
0x52, 0x05, 0x76, 0x61,
-       0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x1a, 0x46, 
0x75, 0x6e, 0x63, 0x74,
-       0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 
0x61, 0x74, 0x69, 0x6f,
-       0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 
0x61, 0x18, 0x01, 0x20,
-       0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 
0x08, 0x70, 0x72, 0x6f,
-       0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 
0x08, 0x70, 0x72, 0x6f,
-       0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x6f, 0x0a, 0x08, 0x49, 0x6e, 0x73, 
0x74, 0x61, 0x6e, 0x63,
-       0x65, 0x12, 0x43, 0x0a, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 
0x6e, 0x4d, 0x65, 0x74,
-       0x61, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 
0x17, 0x2e, 0x70, 0x72,
-       0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
0x4d, 0x65, 0x74, 0x61,
-       0x44, 0x61, 0x74, 0x61, 0x52, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 
0x6f, 0x6e, 0x4d, 0x65,
-       0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 
0x73, 0x74, 0x61, 0x6e,
-       0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 
0x69, 0x6e, 0x73, 0x74,
-       0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x55, 0x0a, 0x0a, 0x41, 0x73, 
0x73, 0x69, 0x67, 0x6e,
-       0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 
0x61, 0x6e, 0x63, 0x65,
-       0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 
0x74, 0x6f, 0x2e, 0x49,
-       0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 
0x74, 0x61, 0x6e, 0x63,
-       0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 
0x64, 0x18, 0x02, 0x20,
-       0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 
0x64, 0x2a, 0x4f, 0x0a,
-       0x14, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x47, 
0x75, 0x61, 0x72, 0x61,
-       0x6e, 0x74, 0x65, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x54, 0x4c, 
0x45, 0x41, 0x53, 0x54,
-       0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 
0x54, 0x4d, 0x4f, 0x53,
-       0x54, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 
0x45, 0x46, 0x46, 0x45,
-       0x43, 0x54, 0x49, 0x56, 0x45, 0x4c, 0x59, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 
0x10, 0x02, 0x2a, 0x3c,
+       0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x67, 
0x0a, 0x17, 0x50, 0x61,
+       0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 
0x6e, 0x4d, 0x65, 0x74,
+       0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x63, 
0x6b, 0x61, 0x67, 0x65,
+       0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 
0x70, 0x61, 0x63, 0x6b,
+       0x61, 0x67, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 
0x72, 0x69, 0x67, 0x69,
+       0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 
0x02, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46, 
0x69, 0x6c, 0x65, 0x4e,
+       0x61, 0x6d, 0x65, 0x22, 0xd5, 0x03, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x63, 
0x74, 0x69, 0x6f, 0x6e,
+       0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0f, 
0x66, 0x75, 0x6e, 0x63,
+       0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 
0x01, 0x20, 0x01, 0x28,
+       0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 
0x6e, 0x63, 0x74, 0x69,
+       0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x66, 
0x75, 0x6e, 0x63, 0x74,
+       0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x48, 
0x0a, 0x0f, 0x70, 0x61,
+       0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 
0x6e, 0x18, 0x02, 0x20,
+       0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 
0x50, 0x61, 0x63, 0x6b,
+       0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 
0x65, 0x74, 0x61, 0x44,
+       0x61, 0x74, 0x61, 0x52, 0x0f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 
0x4c, 0x6f, 0x63, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 
0x69, 0x6f, 0x6e, 0x18,
+       0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 
0x6f, 0x6e, 0x12, 0x1e,
+       0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 
0x18, 0x04, 0x20, 0x01,
+       0x28, 0x04, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 
0x6d, 0x65, 0x12, 0x53,
+       0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 
0x61, 0x74, 0x65, 0x73,
+       0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 
0x74, 0x6f, 0x2e, 0x46,
+       0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 
0x61, 0x74, 0x61, 0x2e,
+       0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 
0x65, 0x73, 0x45, 0x6e,
+       0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 
0x65, 0x53, 0x74, 0x61,
+       0x74, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 
0x69, 0x6f, 0x6e, 0x41,
+       0x75, 0x74, 0x68, 0x53, 0x70, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 
0x0b, 0x32, 0x21, 0x2e,
+       0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 
0x6f, 0x6e, 0x41, 0x75,
+       0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 
0x53, 0x70, 0x65, 0x63,
+       0x52, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 
0x74, 0x68, 0x53, 0x70,
+       0x65, 0x63, 0x1a, 0x57, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 
0x63, 0x65, 0x53, 0x74,
+       0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 
0x03, 0x6b, 0x65, 0x79,
+       0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 
0x2a, 0x0a, 0x05, 0x76,
+       0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 
0x2e, 0x70, 0x72, 0x6f,
+       0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 
0x74, 0x61, 0x74, 0x65,
+       0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 
0x4c, 0x0a, 0x1a, 0x46,
+       0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x65, 
0x6e, 0x74, 0x69, 0x63,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 
0x04, 0x64, 0x61, 0x74,
+       0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 
0x61, 0x12, 0x1a, 0x0a,
+       0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x6f, 0x0a, 
0x08, 0x49, 0x6e, 0x73,
+       0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x66, 0x75, 0x6e, 
0x63, 0x74, 0x69, 0x6f,
+       0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 
0x01, 0x28, 0x0b, 0x32,
+       0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 
0x74, 0x69, 0x6f, 0x6e,
+       0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x52, 0x10, 0x66, 0x75, 
0x6e, 0x63, 0x74, 0x69,
+       0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 
0x0a, 0x0a, 0x69, 0x6e,
+       0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 
0x28, 0x05, 0x52, 0x0a,
+       0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x55, 
0x0a, 0x0a, 0x41, 0x73,
+       0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x08, 
0x69, 0x6e, 0x73, 0x74,
+       0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 
0x2e, 0x70, 0x72, 0x6f,
+       0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 
0x08, 0x69, 0x6e, 0x73,
+       0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 
0x6b, 0x65, 0x72, 0x49,
+       0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 
0x6b, 0x65, 0x72, 0x49,
+       0x64, 0x2a, 0x5b, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 
0x69, 0x6e, 0x67, 0x47,
+       0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x73, 0x12, 0x10, 0x0a, 
0x0c, 0x41, 0x54, 0x4c,
+       0x45, 0x41, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x00, 0x12, 
0x0f, 0x0a, 0x0b, 0x41,
+       0x54, 0x4d, 0x4f, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x01, 
0x12, 0x14, 0x0a, 0x10,
+       0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x49, 0x56, 0x45, 0x4c, 0x59, 0x5f, 
0x4f, 0x4e, 0x43, 0x45,
+       0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c, 
0x10, 0x03, 0x2a, 0x3c,
        0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 
0x6f, 0x6e, 0x54, 0x79,
        0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x45, 0x44, 
0x10, 0x00, 0x12, 0x0c,
        0x0a, 0x08, 0x46, 0x41, 0x49, 0x4c, 0x4f, 0x56, 0x45, 0x52, 0x10, 0x01, 
0x12, 0x0e, 0x0a, 0x0a,
diff --git a/pulsar-function-go/pb/generate.sh 
b/pulsar-function-go/pb/generate.sh
index 5e302e8f7ac..a9e115c46e8 100755
--- a/pulsar-function-go/pb/generate.sh
+++ b/pulsar-function-go/pb/generate.sh
@@ -27,6 +27,8 @@
 #
 # Requirements:
 #  * protoc and protoc-gen-go are installed. See: 
https://github.com/golang/protobuf
+#  * protoc       : v3.17.3
+#  * protoc-gen-go: v1.25.0
 #  * The Pulsar project is checked out somewhere on the file system
 #    in order to source the .proto files
 echo "generate pulsar go function protobuf code..."
diff --git a/pulsar-function-go/pf/instance.go 
b/pulsar-function-go/pf/instance.go
index 8402e9da625..5e05c070e65 100644
--- a/pulsar-function-go/pf/instance.go
+++ b/pulsar-function-go/pf/instance.go
@@ -40,7 +40,7 @@ type goInstance struct {
        producer          pulsar.Producer
        consumers         map[string]pulsar.Consumer
        client            pulsar.Client
-       lastHealthCheckTs int64
+       lastHealthCheckTS int64
        properties        map[string]string
        stats             StatWithLabelValues
 }
@@ -75,7 +75,7 @@ func newGoInstance() *goInstance {
                return producer
        }
 
-       goInstance.lastHealthCheckTs = now.UnixNano()
+       goInstance.lastHealthCheckTS = now.UnixNano()
        goInstance.properties = make(map[string]string)
        goInstance.stats = 
NewStatWithLabelValues(goInstance.getMetricsLabels()...)
        return goInstance
@@ -85,7 +85,7 @@ func (gi *goInstance) processSpawnerHealthCheckTimer(tkr 
*time.Ticker) {
        log.Info("Starting processSpawnerHealthCheckTimer")
        now := time.Now()
        maxIdleTime := gi.context.GetMaxIdleTime()
-       timeSinceLastCheck := now.UnixNano() - gi.lastHealthCheckTs
+       timeSinceLastCheck := now.UnixNano() - gi.lastHealthCheckTS
        if (timeSinceLastCheck) > (maxIdleTime) {
                log.Error("Haven't received health check from spawner in a 
while. Stopping instance...")
                gi.close()
@@ -112,7 +112,7 @@ func (gi *goInstance) startFunction(function function) 
error {
 
        // start process spawner health check timer
        now := time.Now()
-       gi.lastHealthCheckTs = now.UnixNano()
+       gi.lastHealthCheckTS = now.UnixNano()
 
        gi.startScheduler()
 
@@ -349,7 +349,6 @@ func (gi *goInstance) handlerMsg(input pulsar.Message) 
(output []byte, err error
 
 func (gi *goInstance) processResult(msgInput pulsar.Message, output []byte) {
        atLeastOnce := gi.context.instanceConf.funcDetails.ProcessingGuarantees 
== pb.ProcessingGuarantees_ATLEAST_ONCE
-       atMostOnce := gi.context.instanceConf.funcDetails.ProcessingGuarantees 
== pb.ProcessingGuarantees_ATMOST_ONCE
        autoAck := gi.context.instanceConf.funcDetails.AutoAck
 
        // If the function had an output and the user has specified an output 
topic, the output needs to be sent to the
@@ -372,9 +371,9 @@ func (gi *goInstance) processResult(msgInput 
pulsar.Message, output []byte) {
                                        gi.stats.incrTotalSysExceptions(err)
                                        log.Fatal(err)
                                }
-                               // Otherwise the message succeeded. If the SDK 
is entrusted with responding and we are not using
-                               // at-most-once delivery semantics, ack the 
message.
-                               if autoAck && !atMostOnce {
+                               // Otherwise the message succeeded. If the SDK 
is entrusted with responding and we are using
+                               // atLeastOnce delivery semantics, ack the 
message.
+                               if autoAck && atLeastOnce {
                                        gi.ackInputMessage(msgInput)
                                }
                                gi.stats.incrTotalProcessedSuccessfully()
@@ -463,7 +462,7 @@ func (gi *goInstance) close() {
 
 func (gi *goInstance) healthCheck() *pb.HealthCheckResult {
        now := time.Now()
-       gi.lastHealthCheckTs = now.UnixNano()
+       gi.lastHealthCheckTS = now.UnixNano()
        healthCheckResult := pb.HealthCheckResult{Success: true}
        return &healthCheckResult
 }
diff --git a/pulsar-function-go/pf/instanceConf.go 
b/pulsar-function-go/pf/instanceConf.go
index 2fc8d95218e..d60beef29e8 100644
--- a/pulsar-function-go/pf/instanceConf.go
+++ b/pulsar-function-go/pf/instanceConf.go
@@ -43,13 +43,7 @@ type instanceConf struct {
        metricsPort                 int
 }
 
-func newInstanceConf() *instanceConf {
-       config := &conf.Conf{}
-       cfg := config.GetConf()
-       if cfg == nil {
-               panic("config file is nil.")
-       }
-
+func newInstanceConfWithConf(cfg *conf.Conf) *instanceConf {
        instanceConf := &instanceConf{
                instanceID:                  cfg.InstanceID,
                funcID:                      cfg.FuncID,
@@ -103,9 +97,33 @@ func newInstanceConf() *instanceConf {
                        UserConfig: cfg.UserConfig,
                },
        }
+
+       if instanceConf.funcDetails.ProcessingGuarantees == 
pb.ProcessingGuarantees_EFFECTIVELY_ONCE {
+               panic("Go instance current not support EFFECTIVELY_ONCE 
processing guarantees.")
+       }
+
+       if !instanceConf.funcDetails.AutoAck &&
+               (instanceConf.funcDetails.ProcessingGuarantees == 
pb.ProcessingGuarantees_ATMOST_ONCE ||
+                       instanceConf.funcDetails.ProcessingGuarantees == 
pb.ProcessingGuarantees_ATLEAST_ONCE) {
+               panic("When Guarantees == " + 
instanceConf.funcDetails.ProcessingGuarantees.String() +
+                       ", autoAck must be equal to true. If you want not to 
automatically ack, " +
+                       "please configure the processing guarantees as MANUAL." 
+
+                       " This is a contradictory configuration, autoAck will 
be removed later." +
+                       " Please refer to PIP: 
https://github.com/apache/pulsar/issues/15560";)
+       }
+
        return instanceConf
 }
 
+func newInstanceConf() *instanceConf {
+       config := &conf.Conf{}
+       cfg := config.GetConf()
+       if cfg == nil {
+               panic("config file is nil.")
+       }
+       return newInstanceConfWithConf(cfg)
+}
+
 func (ic *instanceConf) getInstanceName() string {
        return "" + fmt.Sprintf("%d", ic.instanceID)
 }
diff --git a/pulsar-function-go/pf/instanceConf_test.go 
b/pulsar-function-go/pf/instanceConf_test.go
index fa87002b71c..02aef913ebc 100644
--- a/pulsar-function-go/pf/instanceConf_test.go
+++ b/pulsar-function-go/pf/instanceConf_test.go
@@ -22,6 +22,8 @@ package pf
 import (
        "testing"
 
+       cfg "github.com/apache/pulsar/pulsar-function-go/conf"
+
        pb "github.com/apache/pulsar/pulsar-function-go/pb"
        "github.com/stretchr/testify/assert"
 )
@@ -96,3 +98,18 @@ func TestInstanceConf_GetInstanceName(t *testing.T) {
 
        assert.Equal(t, "101", instanceName)
 }
+
+func TestInstanceConf_Fail(t *testing.T) {
+       assert.Panics(t, func() {
+               newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 0, 
AutoACK: false})
+       }, "Should have a panic")
+       assert.Panics(t, func() {
+               newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 1, 
AutoACK: false})
+       }, "Should have a panic")
+       assert.Panics(t, func() {
+               newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 2})
+       }, "Should have a panic")
+       assert.NotPanicsf(t, func() {
+               newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 3})
+       }, "Should have a panic")
+}
diff --git a/pulsar-function-go/pf/instance_test.go 
b/pulsar-function-go/pf/instance_test.go
index 85441df5ef4..bf45ae3a891 100644
--- a/pulsar-function-go/pf/instance_test.go
+++ b/pulsar-function-go/pf/instance_test.go
@@ -30,12 +30,12 @@ import (
 )
 
 func testProcessSpawnerHealthCheckTimer(
-       tkr *time.Ticker, lastHealthCheckTs int64, expectedHealthCheckInterval 
int32, counter *int) {
+       tkr *time.Ticker, lastHealthCheckTS int64, expectedHealthCheckInterval 
int32, counter *int) {
        fmt.Println("Starting processSpawnerHealthCheckTimer")
        now := time.Now()
        maxIdleTime := int64(time.Duration(expectedHealthCheckInterval) * 3 * 
time.Second)
        fmt.Println("maxIdleTime is: " + strconv.FormatInt(maxIdleTime, 10))
-       timeSinceLastCheck := now.UnixNano() - lastHealthCheckTs
+       timeSinceLastCheck := now.UnixNano() - lastHealthCheckTS
        fmt.Println("timeSinceLastCheck is: " + 
strconv.FormatInt(timeSinceLastCheck, 10))
        if (timeSinceLastCheck) > (maxIdleTime) {
                fmt.Println("Haven't received health check from spawner in a 
while. Stopping instance...")
@@ -49,7 +49,7 @@ func testProcessSpawnerHealthCheckTimer(
 
 func testStartScheduler(counter *int) {
        now := time.Now()
-       lastHealthCheckTs := now.UnixNano()
+       lastHealthCheckTS := now.UnixNano()
 
        var expectedHealthCheckInterval int32 = 1
        if expectedHealthCheckInterval > 0 {
@@ -61,7 +61,7 @@ func testStartScheduler(counter *int) {
                        tkr := time.NewTicker(period)
                        for range tkr.C {
                                fmt.Println("Starting Timer")
-                               testProcessSpawnerHealthCheckTimer(tkr, 
lastHealthCheckTs, expectedHealthCheckInterval, counter)
+                               testProcessSpawnerHealthCheckTimer(tkr, 
lastHealthCheckTS, expectedHealthCheckInterval, counter)
                        }
                }()
        }
diff --git a/pulsar-function-go/pf/stats.go b/pulsar-function-go/pf/stats.go
index 29c6aa0f026..85a7fff8a38 100644
--- a/pulsar-function-go/pf/stats.go
+++ b/pulsar-function-go/pf/stats.go
@@ -273,8 +273,8 @@ func (stat *StatWithLabelValues) 
incrTotalUserExceptions(err error) {
 func (stat *StatWithLabelValues) addUserException(err error) {
        now := time.Now()
        ts := now.UnixNano()
-       errorTs := LatestException{err, ts}
-       stat.latestUserException = append(stat.latestUserException, errorTs)
+       errorTS := LatestException{err, ts}
+       stat.latestUserException = append(stat.latestUserException, errorTS)
        if len(stat.latestUserException) > 10 {
                stat.latestUserException = stat.latestUserException[1:]
        }
@@ -284,8 +284,8 @@ func (stat *StatWithLabelValues) addUserException(err 
error) {
 
 //@limits(calls=5, period=60)
 func (stat *StatWithLabelValues) reportUserExceptionPrometheus(exception 
error) {
-       errorTs := []string{exception.Error()}
-       exceptionMetricLabels := append(stat.metricsLabels, errorTs...)
+       errorTS := []string{exception.Error()}
+       exceptionMetricLabels := append(stat.metricsLabels, errorTS...)
        userExceptions.WithLabelValues(exceptionMetricLabels...).Set(1.0)
 }
 
@@ -303,8 +303,8 @@ func (stat *StatWithLabelValues) 
incrTotalSysExceptions(exception error) {
 func (stat *StatWithLabelValues) addSysException(exception error) {
        now := time.Now()
        ts := now.UnixNano()
-       errorTs := LatestException{exception, ts}
-       stat.latestSysException = append(stat.latestSysException, errorTs)
+       errorTS := LatestException{exception, ts}
+       stat.latestSysException = append(stat.latestSysException, errorTS)
        if len(stat.latestSysException) > 10 {
                stat.latestSysException = stat.latestSysException[1:]
        }
@@ -314,8 +314,8 @@ func (stat *StatWithLabelValues) addSysException(exception 
error) {
 
 //@limits(calls=5, period=60)
 func (stat *StatWithLabelValues) reportSystemExceptionPrometheus(exception 
error) {
-       errorTs := []string{exception.Error()}
-       exceptionMetricLabels := append(stat.metricsLabels, errorTs...)
+       errorTS := []string{exception.Error()}
+       exceptionMetricLabels := append(stat.metricsLabels, errorTS...)
        systemExceptions.WithLabelValues(exceptionMetricLabels...).Set(1.0)
 }
 
diff --git 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
index b3b165ea536..31d8385c1fc 100644
--- 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
+++ 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
@@ -74,6 +74,7 @@ import 
org.apache.pulsar.functions.instance.stats.SourceStatsManager;
 import org.apache.pulsar.functions.proto.Function;
 import org.apache.pulsar.functions.proto.Function.SinkSpec;
 import org.apache.pulsar.functions.secretsprovider.SecretsProvider;
+import org.apache.pulsar.functions.source.PulsarFunctionRecord;
 import org.apache.pulsar.functions.source.TopicSchema;
 import org.apache.pulsar.functions.utils.FunctionCommon;
 import org.apache.pulsar.functions.utils.SinkConfigUtils;
@@ -248,7 +249,7 @@ class ContextImpl implements Context, SinkContext, 
SourceContext, AutoCloseable
 
     @Override
     public Record<?> getCurrentRecord() {
-        return record;
+        return new PulsarFunctionRecord(record, config.getFunctionDetails());
     }
 
     @Override
diff --git 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
index 61f809a4cbc..7429156ca50 100644
--- 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
+++ 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
@@ -21,6 +21,7 @@ package org.apache.pulsar.functions.instance;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static 
org.apache.pulsar.functions.utils.FunctionCommon.convertFromFunctionDetailsSubscriptionPosition;
 import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.annotations.VisibleForTesting;
 import com.scurrilous.circe.checksum.Crc32cIntChecksum;
 import java.io.IOException;
 import java.util.HashMap;
@@ -350,7 +351,8 @@ public class JavaInstanceRunnable implements AutoCloseable, 
Runnable {
         }
     }
 
-    private void handleResult(Record srcRecord, JavaExecutionResult result) 
throws Exception {
+    @VisibleForTesting
+    void handleResult(Record srcRecord, JavaExecutionResult result) throws 
Exception {
         if (result.getUserException() != null) {
             Exception t = result.getUserException();
             log.warn("Encountered exception when processing message {}",
@@ -361,9 +363,17 @@ public class JavaInstanceRunnable implements 
AutoCloseable, Runnable {
             if (result.getResult() != null) {
                 sendOutputMessage(srcRecord, result.getResult());
             } else {
-                if (instanceConfig.getFunctionDetails().getAutoAck()) {
-                    // the function doesn't produce any result or the user 
doesn't want the result.
-                    srcRecord.ack();
+                org.apache.pulsar.functions.proto.Function.FunctionDetails 
functionDetails =
+                        instanceConfig.getFunctionDetails();
+                // When function return null, needs to be acked directly.
+                if (functionDetails.getProcessingGuarantees()
+                        != 
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.MANUAL) {
+                    // This condition has been automatically acked.
+                    // After waiting to remove the autoAck configuration,can 
be removing the judgment condition.
+                    if (!functionDetails.getAutoAck() || 
functionDetails.getProcessingGuarantees()
+                            != 
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.ATMOST_ONCE) {
+                        srcRecord.ack();
+                    }
                 }
             }
             // increment total successfully processed
diff --git 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
index 80aa49e05ae..2f48efe33dc 100644
--- 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
+++ 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
@@ -277,6 +277,19 @@ public class PulsarSink<T> implements Sink<T> {
         }
     }
 
+    @VisibleForTesting
+    class PulsarSinkManualProcessor extends PulsarSinkAtMostOnceProcessor {
+
+        public PulsarSinkManualProcessor(Schema schema, Crypto crypto) {
+            super(schema, crypto);
+        }
+
+        @Override
+        public void sendOutputMessage(TypedMessageBuilder<T> msg, 
AbstractSinkRecord<T> record) {
+            super.sendOutputMessage(msg, record);
+        }
+    }
+
     @VisibleForTesting
     class PulsarSinkEffectivelyOnceProcessor extends PulsarSinkProcessorBase {
 
@@ -362,6 +375,9 @@ public class PulsarSink<T> implements Sink<T> {
             case EFFECTIVELY_ONCE:
                 this.pulsarSinkProcessor = new 
PulsarSinkEffectivelyOnceProcessor(schema, crypto);
                 break;
+            case MANUAL:
+                this.pulsarSinkProcessor = new 
PulsarSinkManualProcessor(schema, crypto);
+                break;
         }
     }
 
diff --git 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/source/PulsarFunctionRecord.java
 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/source/PulsarFunctionRecord.java
new file mode 100644
index 00000000000..7a27c0a5f38
--- /dev/null
+++ 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/source/PulsarFunctionRecord.java
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pulsar.functions.source;
+
+import java.util.Map;
+import java.util.Optional;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.client.api.Message;
+import org.apache.pulsar.client.api.Schema;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.proto.Function;
+
+/**
+ * The record returned by the proxy to the user.
+ */
+@Slf4j
+public class PulsarFunctionRecord<T> implements Record<T> {
+
+    private final Record<T> record;
+    private final Function.FunctionDetails functionConfig;
+
+    public PulsarFunctionRecord(Record<T> record, Function.FunctionDetails 
functionConfig) {
+        this.record = record;
+        this.functionConfig = functionConfig;
+    }
+
+    @Override
+    public Optional<String> getTopicName() {
+        return record.getTopicName();
+    }
+
+    @Override
+    public Optional<String> getKey() {
+        return record.getKey();
+    }
+
+    @Override
+    public Schema getSchema() {
+        return record.getSchema();
+    }
+
+    @Override
+    public T getValue() {
+        return record.getValue();
+    }
+
+    @Override
+    public Optional<Long> getEventTime() {
+        return record.getEventTime();
+    }
+
+    @Override
+    public Optional<String> getPartitionId() {
+        return record.getPartitionId();
+    }
+
+    @Override
+    public Optional<Integer> getPartitionIndex() {
+        return record.getPartitionIndex();
+    }
+
+    @Override
+    public Optional<Long> getRecordSequence() {
+        return record.getRecordSequence();
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return record.getProperties();
+    }
+
+    @Override
+    public void ack() {
+        Function.ProcessingGuarantees processingGuarantees = 
functionConfig.getProcessingGuarantees();
+        if (processingGuarantees == Function.ProcessingGuarantees.MANUAL) {
+            record.ack();
+        } else {
+            log.warn("Ignore this ack option, under this configuration 
Guarantees:[{}] autoAck:[{}], "
+                    + "the framework will automatically ack", 
processingGuarantees, functionConfig.getAutoAck());
+        }
+    }
+
+    @Override
+    public void fail() {
+        record.fail();
+    }
+
+    @Override
+    public Optional<String> getDestinationTopic() {
+        return record.getDestinationTopic();
+    }
+
+    @Override
+    public Optional<Message<T>> getMessage() {
+        return record.getMessage();
+    }
+}
diff --git 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
index c1f40ea496d..9610912db3f 100644
--- 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
+++ 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
@@ -203,9 +203,6 @@ public class WindowFunctionExecutor<T, X> implements 
Function<T, X> {
         return new WindowLifecycleListener<Event<Record<T>>>() {
             @Override
             public void onExpiry(List<Event<Record<T>>> events) {
-                for (Event<Record<T>> event : events) {
-                    event.getRecord().ack();
-                }
             }
 
             @Override
@@ -234,7 +231,13 @@ public class WindowFunctionExecutor<T, X> implements 
Function<T, X> {
             throw new RuntimeException(e);
         }
         if (output != null) {
-            context.publish(context.getOutputTopic(), output, 
context.getOutputSchemaType());
+            context.publish(context.getOutputTopic(), output, 
context.getOutputSchemaType()).thenAccept(__ -> {
+                if (windowConfig.getProcessingGuarantees() == 
WindowConfig.ProcessingGuarantees.ATLEAST_ONCE) {
+                    for (Record<T> record : tuples) {
+                        record.ack();
+                    }
+                }
+            });
         }
     }
 
@@ -275,8 +278,14 @@ public class WindowFunctionExecutor<T, X> implements 
Function<T, X> {
             initialize(context);
         }
 
+        // record must be PulsarFunctionRecord.
         Record<T> record = (Record<T>) context.getCurrentRecord();
 
+        // windows function processing semantics requires separate processing
+        if (windowConfig.getProcessingGuarantees() == 
WindowConfig.ProcessingGuarantees.ATMOST_ONCE) {
+            record.ack();
+        }
+
         if (isEventTime()) {
             long ts = 
this.timestampExtractor.extractTimestamp(record.getValue());
             if 
(this.waterMarkEventGenerator.track(record.getTopicName().get(), ts)) {
@@ -289,7 +298,6 @@ public class WindowFunctionExecutor<T, X> implements 
Function<T, X> {
                             "Received a late tuple %s with ts %d. This will 
not be " + "processed"
                                     + ".", input, ts));
                 }
-                record.ack();
             }
         } else {
             this.windowManager.add(record, System.currentTimeMillis(), record);
diff --git 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
index 29785181edd..0dbc0d317a6 100644
--- 
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
+++ 
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
@@ -122,10 +122,10 @@ public class WindowManager<T> implements TriggerHandler {
 
         lock.lock();
         try {
-    /*
-     * scan the entire window to handle out of order events in
-     * the case of time based windows.
-     */
+           /*
+            * scan the entire window to handle out of order events in
+            * the case of time based windows.
+            */
             windowEvents = scanEvents(true);
             expired = new ArrayList<>(expiredEvents);
             expiredEvents.clear();
diff --git a/pulsar-functions/instance/src/main/python/Function_pb2.py 
b/pulsar-functions/instance/src/main/python/Function_pb2.py
index 14a33a1255d..eebfe8589d5 100644
--- a/pulsar-functions/instance/src/main/python/Function_pb2.py
+++ b/pulsar-functions/instance/src/main/python/Function_pb2.py
@@ -17,9 +17,10 @@
 # under the License.
 #
 
+# -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: Function.proto
-
+"""Generated protocol buffer code."""
 from google.protobuf.internal import enum_type_wrapper
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
@@ -38,7 +39,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'\n!org.apache.pulsar.functions.protoB\010Function',
   create_key=_descriptor._internal_create_key,
-  
serialized_pb=b'\n\x0e\x46unction.proto\x12\x05proto\"3\n\tResources\x12\x0b\n\x03\x63pu\x18\x01
 \x01(\x01\x12\x0b\n\x03ram\x18\x02 \x01(\x03\x12\x0c\n\x04\x64isk\x18\x03 
\x01(\x03\"B\n\x0cRetryDetails\x12\x19\n\x11maxMessageRetries\x18\x01 
\x01(\x05\x12\x17\n\x0f\x64\x65\x61\x64LetterTopic\x18\x02 
\x01(\t\"\xa2\x06\n\x0f\x46unctionDetails\x12\x0e\n\x06tenant\x18\x01 
\x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 
\x01(\t\x12\x11\n\tclassName\x18\x04 \x01(\t\x12\ [...]
+  
serialized_pb=b'\n\x0e\x46unction.proto\x12\x05proto\"3\n\tResources\x12\x0b\n\x03\x63pu\x18\x01
 \x01(\x01\x12\x0b\n\x03ram\x18\x02 \x01(\x03\x12\x0c\n\x04\x64isk\x18\x03 
\x01(\x03\"B\n\x0cRetryDetails\x12\x19\n\x11maxMessageRetries\x18\x01 
\x01(\x05\x12\x17\n\x0f\x64\x65\x61\x64LetterTopic\x18\x02 
\x01(\t\"\xa6\x06\n\x0f\x46unctionDetails\x12\x0e\n\x06tenant\x18\x01 
\x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 
\x01(\t\x12\x11\n\tclassName\x18\x04 \x01(\t\x12\ [...]
 )
 
 _PROCESSINGGUARANTEES = _descriptor.EnumDescriptor(
@@ -63,11 +64,16 @@ _PROCESSINGGUARANTEES = _descriptor.EnumDescriptor(
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='MANUAL', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3685,
-  serialized_end=3764,
+  serialized_start=3711,
+  serialized_end=3802,
 )
 _sym_db.RegisterEnumDescriptor(_PROCESSINGGUARANTEES)
 
@@ -97,8 +103,8 @@ _SUBSCRIPTIONTYPE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3766,
-  serialized_end=3826,
+  serialized_start=3804,
+  serialized_end=3864,
 )
 _sym_db.RegisterEnumDescriptor(_SUBSCRIPTIONTYPE)
 
@@ -123,8 +129,8 @@ _SUBSCRIPTIONPOSITION = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3828,
-  serialized_end=3876,
+  serialized_start=3866,
+  serialized_end=3914,
 )
 _sym_db.RegisterEnumDescriptor(_SUBSCRIPTIONPOSITION)
 
@@ -149,8 +155,8 @@ _FUNCTIONSTATE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3878,
-  serialized_end=3919,
+  serialized_start=3916,
+  serialized_end=3957,
 )
 _sym_db.RegisterEnumDescriptor(_FUNCTIONSTATE)
 
@@ -158,6 +164,7 @@ FunctionState = 
enum_type_wrapper.EnumTypeWrapper(_FUNCTIONSTATE)
 ATLEAST_ONCE = 0
 ATMOST_ONCE = 1
 EFFECTIVELY_ONCE = 2
+MANUAL = 3
 SHARED = 0
 FAILOVER = 1
 KEY_SHARED = 2
@@ -192,8 +199,8 @@ _FUNCTIONDETAILS_RUNTIME = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=844,
-  serialized_end=883,
+  serialized_start=848,
+  serialized_end=887,
 )
 _sym_db.RegisterEnumDescriptor(_FUNCTIONDETAILS_RUNTIME)
 
@@ -227,8 +234,8 @@ _FUNCTIONDETAILS_COMPONENTTYPE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=885,
-  serialized_end=949,
+  serialized_start=889,
+  serialized_end=953,
 )
 _sym_db.RegisterEnumDescriptor(_FUNCTIONDETAILS_COMPONENTTYPE)
 
@@ -262,8 +269,8 @@ _CRYPTOSPEC_FAILUREACTION = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=1873,
-  serialized_end=1934,
+  serialized_start=1899,
+  serialized_end=1960,
 )
 _sym_db.RegisterEnumDescriptor(_CRYPTOSPEC_FAILUREACTION)
 
@@ -430,7 +437,7 @@ _FUNCTIONDETAILS = _descriptor.Descriptor(
       has_default_value=False, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  
create_key=_descriptor._internal_create_key),
+      serialized_options=b'\030\001', file=DESCRIPTOR,  
create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
       name='parallelism', full_name='proto.FunctionDetails.parallelism', 
index=10,
       number=10, type=5, cpp_type=1, label=1,
@@ -537,7 +544,7 @@ _FUNCTIONDETAILS = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=147,
-  serialized_end=949,
+  serialized_end=953,
 )
 
 
@@ -568,8 +575,8 @@ _CONSUMERSPEC_RECEIVERQUEUESIZE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1283,
-  serialized_end=1317,
+  serialized_start=1309,
+  serialized_end=1343,
 )
 
 _CONSUMERSPEC_SCHEMAPROPERTIESENTRY = _descriptor.Descriptor(
@@ -606,8 +613,8 @@ _CONSUMERSPEC_SCHEMAPROPERTIESENTRY = 
_descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1319,
-  serialized_end=1374,
+  serialized_start=1345,
+  serialized_end=1400,
 )
 
 _CONSUMERSPEC_CONSUMERPROPERTIESENTRY = _descriptor.Descriptor(
@@ -644,8 +651,8 @@ _CONSUMERSPEC_CONSUMERPROPERTIESENTRY = 
_descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1376,
-  serialized_end=1433,
+  serialized_start=1402,
+  serialized_end=1459,
 )
 
 _CONSUMERSPEC = _descriptor.Descriptor(
@@ -705,6 +712,13 @@ _CONSUMERSPEC = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  
create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='poolMessages', full_name='proto.ConsumerSpec.poolMessages', 
index=7,
+      number=8, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  
create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -717,8 +731,8 @@ _CONSUMERSPEC = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=952,
-  serialized_end=1433,
+  serialized_start=956,
+  serialized_end=1459,
 )
 
 
@@ -777,8 +791,8 @@ _PRODUCERSPEC = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1436,
-  serialized_end=1616,
+  serialized_start=1462,
+  serialized_end=1642,
 )
 
 
@@ -838,8 +852,8 @@ _CRYPTOSPEC = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1619,
-  serialized_end=1934,
+  serialized_start=1645,
+  serialized_end=1960,
 )
 
 
@@ -877,8 +891,8 @@ _SOURCESPEC_TOPICSTOSERDECLASSNAMEENTRY = 
_descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2414,
-  serialized_end=2475,
+  serialized_start=2440,
+  serialized_end=2501,
 )
 
 _SOURCESPEC_INPUTSPECSENTRY = _descriptor.Descriptor(
@@ -915,8 +929,8 @@ _SOURCESPEC_INPUTSPECSENTRY = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2477,
-  serialized_end=2547,
+  serialized_start=2503,
+  serialized_end=2573,
 )
 
 _SOURCESPEC = _descriptor.Descriptor(
@@ -1030,8 +1044,8 @@ _SOURCESPEC = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1937,
-  serialized_end=2547,
+  serialized_start=1963,
+  serialized_end=2573,
 )
 
 
@@ -1069,8 +1083,8 @@ _SINKSPEC_SCHEMAPROPERTIESENTRY = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1319,
-  serialized_end=1374,
+  serialized_start=1345,
+  serialized_end=1400,
 )
 
 _SINKSPEC_CONSUMERPROPERTIESENTRY = _descriptor.Descriptor(
@@ -1107,8 +1121,8 @@ _SINKSPEC_CONSUMERPROPERTIESENTRY = 
_descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1376,
-  serialized_end=1433,
+  serialized_start=1402,
+  serialized_end=1459,
 )
 
 _SINKSPEC = _descriptor.Descriptor(
@@ -1208,8 +1222,8 @@ _SINKSPEC = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2550,
-  serialized_end=3026,
+  serialized_start=2576,
+  serialized_end=3052,
 )
 
 
@@ -1247,8 +1261,8 @@ _PACKAGELOCATIONMETADATA = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3028,
-  serialized_end=3100,
+  serialized_start=3054,
+  serialized_end=3126,
 )
 
 
@@ -1286,8 +1300,8 @@ _FUNCTIONMETADATA_INSTANCESTATESENTRY = 
_descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3396,
-  serialized_end=3471,
+  serialized_start=3422,
+  serialized_end=3497,
 )
 
 _FUNCTIONMETADATA = _descriptor.Descriptor(
@@ -1352,8 +1366,8 @@ _FUNCTIONMETADATA = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3103,
-  serialized_end=3471,
+  serialized_start=3129,
+  serialized_end=3497,
 )
 
 
@@ -1391,8 +1405,8 @@ _FUNCTIONAUTHENTICATIONSPEC = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3473,
-  serialized_end=3533,
+  serialized_start=3499,
+  serialized_end=3559,
 )
 
 
@@ -1430,8 +1444,8 @@ _INSTANCE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3535,
-  serialized_end=3616,
+  serialized_start=3561,
+  serialized_end=3642,
 )
 
 
@@ -1469,8 +1483,8 @@ _ASSIGNMENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3618,
-  serialized_end=3683,
+  serialized_start=3644,
+  serialized_end=3709,
 )
 
 _FUNCTIONDETAILS.fields_by_name['processingGuarantees'].enum_type = 
_PROCESSINGGUARANTEES
@@ -1690,6 +1704,7 @@ _sym_db.RegisterMessage(Assignment)
 
 
 DESCRIPTOR._options = None
+_FUNCTIONDETAILS.fields_by_name['autoAck']._options = None
 _CONSUMERSPEC_SCHEMAPROPERTIESENTRY._options = None
 _CONSUMERSPEC_CONSUMERPROPERTIESENTRY._options = None
 _SOURCESPEC_TOPICSTOSERDECLASSNAMEENTRY._options = None
diff --git a/pulsar-functions/instance/src/main/python/python_instance.py 
b/pulsar-functions/instance/src/main/python/python_instance.py
index 1a04029ed81..46c01c2ddd4 100755
--- a/pulsar-functions/instance/src/main/python/python_instance.py
+++ b/pulsar-functions/instance/src/main/python/python_instance.py
@@ -100,6 +100,7 @@ class PythonInstance(object):
     self.execution_thread = None
     self.atmost_once = 
self.instance_config.function_details.processingGuarantees == 
Function_pb2.ProcessingGuarantees.Value('ATMOST_ONCE')
     self.atleast_once = 
self.instance_config.function_details.processingGuarantees == 
Function_pb2.ProcessingGuarantees.Value('ATLEAST_ONCE')
+    self.manual = self.instance_config.function_details.processingGuarantees 
== Function_pb2.ProcessingGuarantees.Value('MANUAL')
     self.auto_ack = self.instance_config.function_details.autoAck
     self.contextimpl = None
     self.last_health_check_ts = time.time()
@@ -269,7 +270,7 @@ class PythonInstance(object):
 
   def done_producing(self, consumer, orig_message, topic, result, 
sent_message):
     if result == pulsar.Result.Ok:
-      if self.auto_ack:
+      if self.auto_ack and self.atleast_once:
         consumer.acknowledge(orig_message)
     else:
       error_msg = "Failed to publish to topic [%s] with error [%s] with src 
message id [%s]" % (topic, result, orig_message.message_id())
diff --git a/pulsar-functions/instance/src/main/python/python_instance_main.py 
b/pulsar-functions/instance/src/main/python/python_instance_main.py
index 5817e5958e6..631d5b47851 100755
--- a/pulsar-functions/instance/src/main/python/python_instance_main.py
+++ b/pulsar-functions/instance/src/main/python/python_instance_main.py
@@ -97,6 +97,18 @@ def main():
     args.function_details = args.function_details[:-1]
   json_format.Parse(args.function_details, function_details)
 
+  if function_details.processingGuarantees == "EFFECTIVELY_ONCE":
+    print("Python instance current not support EFFECTIVELY_ONCE processing 
guarantees.")
+    sys.exit(1)
+
+  if function_details.autoAck == False and 
function_details.processingGuarantees == "ATMOST_ONCE" \
+          or function_details.processingGuarantees == "ATLEAST_ONCE":
+    print("When Guarantees == " + function_details.processingGuarantees + ", 
autoAck must be equal to true, "
+          "This is a contradictory configuration, autoAck will be removed 
later,"
+          "If you want not to automatically ack, please configure the 
processing guarantees as MANUAL."
+          "This is a contradictory configuration, autoAck will be removed 
later," 
+          "Please refer to PIP: https://github.com/apache/pulsar/issues/15560";)
+    sys.exit(1)
   if os.path.splitext(str(args.py))[1] == '.whl':
     if args.install_usercode_dependencies:
       cmd = "pip install -t %s" % os.path.dirname(str(args.py))
diff --git 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
index 13c467e1e50..a5fe51d5403 100644
--- 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
+++ 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
@@ -55,6 +55,7 @@ import org.apache.pulsar.client.impl.PulsarClientImpl;
 import org.apache.pulsar.client.impl.TypedMessageBuilderImpl;
 import org.apache.pulsar.client.impl.conf.ProducerConfigurationData;
 import org.apache.pulsar.common.io.SinkConfig;
+import org.apache.pulsar.common.io.SourceConfig;
 import org.apache.pulsar.common.naming.TopicName;
 import org.apache.pulsar.functions.api.Record;
 import org.apache.pulsar.functions.instance.state.BKStateStoreImpl;
@@ -62,7 +63,9 @@ import 
org.apache.pulsar.functions.instance.state.InstanceStateManager;
 import org.apache.pulsar.functions.instance.stats.FunctionCollectorRegistry;
 import org.apache.pulsar.functions.proto.Function.FunctionDetails;
 import 
org.apache.pulsar.functions.secretsprovider.EnvironmentBasedSecretsProvider;
+import org.apache.pulsar.functions.source.PulsarFunctionRecord;
 import org.apache.pulsar.io.core.SinkContext;
+import org.apache.pulsar.io.core.SourceContext;
 import org.assertj.core.util.Lists;
 import org.mockito.Mockito;
 import org.slf4j.Logger;
@@ -152,11 +155,17 @@ public class ContextImplTest {
 
     @Test
     public void testGetSourceConfig() {
-        SinkContext sourceContext = context;
-        SinkConfig sinkConfig = sourceContext.getSinkConfig();
+        SourceContext sourceContext = context;
+        SourceConfig sinkConfig = sourceContext.getSourceConfig();
         Assert.assertNotNull(sinkConfig);
     }
 
+    @Test
+    public void testGetCurrentRecord() {
+        Record<?> currentRecord = context.getCurrentRecord();
+        assertTrue(currentRecord instanceof PulsarFunctionRecord<?>);
+    }
+
     @Test
     public void testIncrCounterStateEnabled() throws Exception {
         context.defaultStateStore = mock(BKStateStoreImpl.class);
diff --git 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
index ec478e2beaf..5029a064311 100644
--- 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
+++ 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
@@ -18,10 +18,14 @@
  */
 package org.apache.pulsar.functions.instance;
 
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.Map;
 import lombok.Getter;
@@ -29,12 +33,15 @@ import lombok.Setter;
 import org.apache.pulsar.client.api.ClientBuilder;
 import org.apache.pulsar.functions.api.Context;
 import org.apache.pulsar.functions.api.Function;
+import org.apache.pulsar.functions.api.Record;
 import org.apache.pulsar.functions.api.SerDe;
+import org.apache.pulsar.functions.instance.stats.ComponentStatsManager;
 import org.apache.pulsar.functions.proto.Function.FunctionDetails;
 import org.apache.pulsar.functions.proto.Function.SinkSpec;
 import org.apache.pulsar.functions.proto.Function.SinkSpecOrBuilder;
 import org.apache.pulsar.functions.proto.Function.SourceSpecOrBuilder;
 import org.apache.pulsar.functions.proto.InstanceCommunication;
+import org.jetbrains.annotations.NotNull;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -52,21 +59,25 @@ public class JavaInstanceRunnableTest {
         }
     }
 
-    private static InstanceConfig createInstanceConfig(String outputSerde) {
-        FunctionDetails.Builder functionDetailsBuilder = 
FunctionDetails.newBuilder();
-        if (outputSerde != null) {
-            
functionDetailsBuilder.setSink(SinkSpec.newBuilder().setSerDeClassName(outputSerde).build());
-        }
+    private static InstanceConfig createInstanceConfig(FunctionDetails 
functionDetails) {
         InstanceConfig instanceConfig = new InstanceConfig();
-        instanceConfig.setFunctionDetails(functionDetailsBuilder.build());
+        instanceConfig.setFunctionDetails(functionDetails);
         instanceConfig.setMaxBufferedTuples(1024);
         return instanceConfig;
     }
 
     private JavaInstanceRunnable createRunnable(String outputSerde) throws 
Exception {
-        InstanceConfig config = createInstanceConfig(outputSerde);
+        FunctionDetails.Builder functionDetailsBuilder = 
FunctionDetails.newBuilder();
+        if (outputSerde != null) {
+            
functionDetailsBuilder.setSink(SinkSpec.newBuilder().setSerDeClassName(outputSerde).build());
+        }
+        return createRunnable(functionDetailsBuilder.build());
+    }
+
+    private JavaInstanceRunnable createRunnable(FunctionDetails 
functionDetails) throws Exception {
         ClientBuilder clientBuilder = mock(ClientBuilder.class);
         when(clientBuilder.build()).thenReturn(null);
+        InstanceConfig config = createInstanceConfig(functionDetails);
         JavaInstanceRunnable javaInstanceRunnable = new JavaInstanceRunnable(
                 config, clientBuilder, null, null, null, null, null, null, 
null);
         return javaInstanceRunnable;
@@ -119,9 +130,51 @@ public class JavaInstanceRunnableTest {
         }
     }
 
+    @Test
+    public void testFunctionResultNull() throws Exception {
+        JavaExecutionResult javaExecutionResult = new JavaExecutionResult();
+
+        // ProcessingGuarantees == MANUAL, not need ack.
+        Record record = mock(Record.class);
+        getJavaInstanceRunnable(true, 
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.MANUAL)
+                .handleResult(record, javaExecutionResult);
+        verify(record, times(0)).ack();
+
+        // ProcessingGuarantees == ATMOST_ONCE and autoAck == true, not need 
ack
+        clearInvocations(record);
+        getJavaInstanceRunnable(true, 
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.ATMOST_ONCE)
+                .handleResult(record, javaExecutionResult);
+        verify(record, times(0)).ack();
+
+        // other case, need ack
+        clearInvocations(record);
+        getJavaInstanceRunnable(true, 
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.ATLEAST_ONCE)
+                .handleResult(record, javaExecutionResult);
+        verify(record, times(1)).ack();
+        clearInvocations(record);
+        getJavaInstanceRunnable(true, 
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.EFFECTIVELY_ONCE)
+                .handleResult(record, javaExecutionResult);
+        verify(record, times(1)).ack();
+    }
+
+    @NotNull
+    private JavaInstanceRunnable getJavaInstanceRunnable(boolean autoAck,
+            org.apache.pulsar.functions.proto.Function.ProcessingGuarantees 
processingGuarantees) throws Exception {
+        FunctionDetails functionDetails = FunctionDetails.newBuilder()
+                .setAutoAck(autoAck)
+                .setProcessingGuarantees(processingGuarantees).build();
+        JavaInstanceRunnable javaInstanceRunnable = 
createRunnable(functionDetails);
+
+        Field stats = JavaInstanceRunnable.class.getDeclaredField("stats");
+        stats.setAccessible(true);
+        stats.set(javaInstanceRunnable, mock(ComponentStatsManager.class));
+        stats.setAccessible(false);
+        return javaInstanceRunnable;
+    }
+
     @Test
     public void testStatsManagerNull() throws Exception {
-        JavaInstanceRunnable javaInstanceRunnable = createRunnable(null);
+        JavaInstanceRunnable javaInstanceRunnable = createRunnable((String) 
null);
 
         Assert.assertEquals(javaInstanceRunnable.getFunctionStatus().build(),
                 InstanceCommunication.FunctionStatus.newBuilder().build());
diff --git 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
index 94878e33c57..93104c5eee2 100644
--- 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
+++ 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
@@ -337,9 +337,9 @@ public class PulsarSinkTest {
         pulsarConfig.setTopic(defaultTopic);
         PulsarClient pulsarClient;
 
-        /** test At-least-once **/
+        /** test MANUAL **/
         pulsarClient = getPulsarClient();
-        
pulsarConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
+        pulsarConfig.setProcessingGuarantees(ProcessingGuarantees.MANUAL);
         PulsarSink pulsarSink = new PulsarSink(pulsarClient, pulsarConfig, new 
HashMap<>(), mock(ComponentStatsManager.class), 
Thread.currentThread().getContextClassLoader());
 
         pulsarSink.open(new HashMap<>(), mock(SinkContext.class));
@@ -362,6 +362,46 @@ public class PulsarSinkTest {
 
             pulsarSink.write(record);
 
+            Assert.assertTrue(pulsarSink.pulsarSinkProcessor instanceof 
PulsarSink.PulsarSinkManualProcessor);
+            PulsarSink.PulsarSinkManualProcessor pulsarSinkManualProcessor
+                    = (PulsarSink.PulsarSinkManualProcessor) 
pulsarSink.pulsarSinkProcessor;
+            if (topic != null) {
+                
Assert.assertTrue(pulsarSinkManualProcessor.publishProducers.containsKey(topic));
+            } else {
+                
Assert.assertTrue(pulsarSinkManualProcessor.publishProducers.containsKey(defaultTopic));
+            }
+            verify(pulsarClient.newProducer(), 
times(1)).topic(argThat(otherTopic -> {
+                if (topic != null) {
+                    return topic.equals(otherTopic);
+                } else {
+                    return defaultTopic.equals(otherTopic);
+                }
+            }));
+        }
+
+        /** test At-least-once **/
+        pulsarClient = getPulsarClient();
+        
pulsarConfig.setProcessingGuarantees(ProcessingGuarantees.ATLEAST_ONCE);
+        pulsarSink = new PulsarSink(pulsarClient, pulsarConfig, new 
HashMap<>(), mock(ComponentStatsManager.class), 
Thread.currentThread().getContextClassLoader());
+
+        pulsarSink.open(new HashMap<>(), mock(SinkContext.class));
+
+        for (String topic : topics) {
+
+            SinkRecord<String> record = new SinkRecord<>(new Record<String>() {
+
+                @Override
+                public String getValue() {
+                    return "in1";
+                }
+
+                @Override
+                public Optional<String> getDestinationTopic() {
+                    return getTopicOptional(topic);
+                }
+            }, "out1");
+            pulsarSink.write(record);
+
             Assert.assertTrue(pulsarSink.pulsarSinkProcessor instanceof 
PulsarSink.PulsarSinkAtLeastOnceProcessor);
             PulsarSink.PulsarSinkAtLeastOnceProcessor 
pulsarSinkAtLeastOnceProcessor
                     = (PulsarSink.PulsarSinkAtLeastOnceProcessor) 
pulsarSink.pulsarSinkProcessor;
@@ -381,7 +421,7 @@ public class PulsarSinkTest {
 
         /** test At-most-once **/
         pulsarClient = getPulsarClient();
-        
pulsarConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATMOST_ONCE);
+        pulsarConfig.setProcessingGuarantees(ProcessingGuarantees.ATMOST_ONCE);
         pulsarSink = new PulsarSink(pulsarClient, pulsarConfig, new 
HashMap<>(), mock(ComponentStatsManager.class),
                 Thread.currentThread().getContextClassLoader());
 
diff --git 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/source/PulsarFunctionRecordTest.java
 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/source/PulsarFunctionRecordTest.java
new file mode 100644
index 00000000000..f4f857354e8
--- /dev/null
+++ 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/source/PulsarFunctionRecordTest.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pulsar.functions.source;
+
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.testng.Assert.*;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.proto.Function;
+import org.testng.annotations.Test;
+
+public class PulsarFunctionRecordTest {
+
+    @Test
+    public void testAck() {
+        Record record = mock(Record.class);
+        Function.FunctionDetails functionDetails = 
Function.FunctionDetails.newBuilder().setAutoAck(true)
+                
.setProcessingGuarantees(Function.ProcessingGuarantees.ATMOST_ONCE).build();
+        PulsarFunctionRecord pulsarFunctionRecord = new 
PulsarFunctionRecord<>(record, functionDetails);
+        pulsarFunctionRecord.ack();
+        verify(record, times(0)).ack();
+
+        clearInvocations(record);
+        functionDetails = 
Function.FunctionDetails.newBuilder().setAutoAck(true)
+                
.setProcessingGuarantees(Function.ProcessingGuarantees.ATLEAST_ONCE).build();
+        pulsarFunctionRecord = new PulsarFunctionRecord<>(record, 
functionDetails);
+        pulsarFunctionRecord.ack();
+        verify(record, times(0)).ack();
+
+        clearInvocations(record);
+        functionDetails = 
Function.FunctionDetails.newBuilder().setAutoAck(true)
+                
.setProcessingGuarantees(Function.ProcessingGuarantees.EFFECTIVELY_ONCE).build();
+        pulsarFunctionRecord = new PulsarFunctionRecord<>(record, 
functionDetails);
+        pulsarFunctionRecord.ack();
+        verify(record, times(0)).ack();
+
+        clearInvocations(record);
+        functionDetails = 
Function.FunctionDetails.newBuilder().setAutoAck(true)
+                
.setProcessingGuarantees(Function.ProcessingGuarantees.MANUAL).build();
+        pulsarFunctionRecord = new PulsarFunctionRecord<>(record, 
functionDetails);
+        pulsarFunctionRecord.ack();
+        verify(record, times(1)).ack();
+    }
+}
diff --git 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
index 8efc8d0e1ee..bf74824efed 100644
--- 
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
+++ 
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
@@ -20,8 +20,12 @@ package org.apache.pulsar.functions.windowing;
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
@@ -127,6 +131,46 @@ public class WindowFunctionExecutorTest {
         testWindowedPulsarFunction.shutdown();
     }
 
+    @Test
+    public void testWindowFunctionWithAtmostOnce() throws Exception {
+        
windowConfig.setProcessingGuarantees(WindowConfig.ProcessingGuarantees.ATMOST_ONCE);
+        doReturn(Optional.of(new Gson().fromJson(new 
Gson().toJson(windowConfig), Map.class))).when(context)
+                .getUserConfigValue(WindowConfig.WINDOW_CONFIG_KEY);
+        Record record = mock(Record.class);
+        when(context.getCurrentRecord()).thenReturn(record);
+        doReturn(Optional.of("test-topic")).when(record).getTopicName();
+        doReturn(record).when(context).getCurrentRecord();
+        doReturn(100l).when(record).getValue();
+        testWindowedPulsarFunction.process(10L, context);
+        verify(record, times(1)).ack();
+    }
+
+    @Test
+    public void testWindowFunctionWithAtleastOnce() throws Exception {
+
+        WindowConfig config = new WindowConfig();
+        
config.setProcessingGuarantees(WindowConfig.ProcessingGuarantees.ATLEAST_ONCE);
+        WindowFunctionExecutor windowFunctionExecutor = 
spy(WindowFunctionExecutor.class);
+        windowFunctionExecutor.windowConfig = config;
+        doNothing().when(windowFunctionExecutor).initialize(any());
+        doReturn(new 
Object()).when(windowFunctionExecutor).process(any(Window.class), 
any(WindowContext.class));
+        
doReturn(CompletableFuture.completedFuture(null)).when(context).publish(any(), 
any(), any());
+
+        List<Event<Record<Long>>> tuples = new ArrayList<>();
+        tuples.add(new EventImpl<>(mock(Record.class), 0l, 
mock(Record.class)));
+        WindowLifecycleListener<Event<Record<Long>>> 
eventWindowLifecycleListener =
+                windowFunctionExecutor.newWindowLifecycleListener(context);
+
+        eventWindowLifecycleListener.onExpiry(tuples);
+        for (Event<Record<Long>> tuple : tuples) {
+            verify(tuple.getRecord(), times(0)).ack();
+        }
+
+        eventWindowLifecycleListener.onActivation(tuples, new ArrayList<>(), 
new ArrayList<>(), 0l);
+        for (Event<Record<Long>> tuple : tuples) {
+            verify(tuple.get(), times(1)).ack();
+        }
+    }
     @Test(expectedExceptions = RuntimeException.class)
     public void testExecuteWithWrongWrongTimestampExtractorType() throws 
Exception {
         WindowConfig windowConfig = new WindowConfig();
diff --git a/pulsar-functions/proto/src/main/proto/Function.proto 
b/pulsar-functions/proto/src/main/proto/Function.proto
index 02520be305b..09ff9cfc8eb 100644
--- a/pulsar-functions/proto/src/main/proto/Function.proto
+++ b/pulsar-functions/proto/src/main/proto/Function.proto
@@ -27,6 +27,7 @@ enum ProcessingGuarantees {
     ATLEAST_ONCE = 0; // [default value]
     ATMOST_ONCE = 1;
     EFFECTIVELY_ONCE = 2;
+    MANUAL = 3;
 }
 
 enum SubscriptionType {
@@ -72,7 +73,8 @@ message FunctionDetails {
     string userConfig = 7;
     string secretsMap = 16;
     Runtime runtime = 8;
-    bool autoAck = 9;
+    // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+    bool autoAck = 9 [deprecated = true];
     int32 parallelism = 10;
     SourceSpec source = 11;
     SinkSpec sink = 12;
diff --git 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
index 69b4dcfd647..d24542185e5 100644
--- 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
+++ 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
@@ -308,11 +308,22 @@ public class FunctionConfigUtils {
         // windowing related
         WindowConfig windowConfig = functionConfig.getWindowConfig();
         if (windowConfig != null) {
+            // Windows Function not support MANUAL and EFFECTIVELY_ONCE.
+            if (functionConfig.getProcessingGuarantees() == 
FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE
+                    || functionConfig.getProcessingGuarantees() == 
FunctionConfig.ProcessingGuarantees.MANUAL) {
+                throw new IllegalArgumentException(
+                        "Windows Function not support "
+                                + functionConfig.getProcessingGuarantees() + " 
delivery semantics.");
+            } else {
+                // Override functionConfig.getProcessingGuarantees to MANUAL, 
and set windowsFunction is guarantees
+                
windowConfig.setProcessingGuarantees(WindowConfig.ProcessingGuarantees
+                        
.valueOf(functionDetailsBuilder.getProcessingGuarantees().name()));
+                
functionDetailsBuilder.setProcessingGuarantees(Function.ProcessingGuarantees.MANUAL);
+            }
             
windowConfig.setActualWindowFunctionClassName(extractedDetails.getFunctionClassName());
             configs.put(WindowConfig.WINDOW_CONFIG_KEY, windowConfig);
             // set class name to window function executor
             
functionDetailsBuilder.setClassName("org.apache.pulsar.functions.windowing.WindowFunctionExecutor");
-
         } else {
             if (extractedDetails.getFunctionClassName() != null) {
                 
functionDetailsBuilder.setClassName(extractedDetails.getFunctionClassName());
@@ -321,7 +332,6 @@ public class FunctionConfigUtils {
         if (!configs.isEmpty()) {
             functionDetailsBuilder.setUserConfig(new Gson().toJson(configs));
         }
-
         if (functionConfig.getSecrets() != null && 
!functionConfig.getSecrets().isEmpty()) {
             functionDetailsBuilder.setSecretsMap(new 
Gson().toJson(functionConfig.getSecrets()));
         }
@@ -361,10 +371,26 @@ public class FunctionConfigUtils {
             functionDetailsBuilder.setBuiltin(builtin);
         }
 
-        return functionDetailsBuilder.build();
+        return validateFunctionDetails(functionDetailsBuilder.build());
+    }
+
+    public static FunctionDetails validateFunctionDetails(FunctionDetails 
functionDetails)
+            throws IllegalArgumentException {
+        if (!functionDetails.getAutoAck() && 
functionDetails.getProcessingGuarantees()
+                == Function.ProcessingGuarantees.ATMOST_ONCE) {
+            throw new IllegalArgumentException("When Guarantees == 
ATMOST_ONCE, autoAck must be equal to true."
+                    + " This is a contradictory configuration, autoAck will be 
removed later."
+                    + " Please refer to PIP: 
https://github.com/apache/pulsar/issues/15560";);
+        }
+        if (!functionDetails.getAutoAck()) {
+            log.warn("The autoAck configuration will be deprecated in the 
future."
+                    + " If you want not to automatically ack, please configure 
the processing guarantees as MANUAL.");
+        }
+        return functionDetails;
     }
 
     public static FunctionConfig convertFromDetails(FunctionDetails 
functionDetails) {
+        functionDetails = validateFunctionDetails(functionDetails);
         FunctionConfig functionConfig = new FunctionConfig();
         functionConfig.setTenant(functionDetails.getTenant());
         functionConfig.setNamespace(functionDetails.getNamespace());
@@ -463,6 +489,10 @@ public class FunctionConfigUtils {
                     (new 
Gson().toJson(userConfig.get(WindowConfig.WINDOW_CONFIG_KEY))),
                     WindowConfig.class);
             userConfig.remove(WindowConfig.WINDOW_CONFIG_KEY);
+            if (windowConfig.getProcessingGuarantees() != null) {
+                functionConfig.setProcessingGuarantees(
+                        
FunctionConfig.ProcessingGuarantees.valueOf(windowConfig.getProcessingGuarantees().name()));
+            }
             
functionConfig.setClassName(windowConfig.getActualWindowFunctionClassName());
             functionConfig.setWindowConfig(windowConfig);
         } else {
diff --git 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
index a2f0fdde7a2..31b147a1caf 100644
--- 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
+++ 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
@@ -177,6 +177,7 @@ public class SinkConfigUtils {
         } else {
             functionDetailsBuilder.setAutoAck(true);
         }
+
         if (sinkConfig.getTimeoutMs() != null) {
             sourceSpecBuilder.setTimeoutMs(sinkConfig.getTimeoutMs());
         }
@@ -253,7 +254,7 @@ public class SinkConfigUtils {
             
functionDetailsBuilder.setCustomRuntimeOptions(sinkConfig.getCustomRuntimeOptions());
         }
 
-        return functionDetailsBuilder.build();
+        return 
FunctionConfigUtils.validateFunctionDetails(functionDetailsBuilder.build());
     }
 
     public static SinkConfig convertFromDetails(FunctionDetails 
functionDetails) {
diff --git 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
index bcb847869e6..f8fc091aece 100644
--- 
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
+++ 
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
@@ -196,7 +196,7 @@ public class SourceConfigUtils {
             
functionDetailsBuilder.setCustomRuntimeOptions(sourceConfig.getCustomRuntimeOptions());
         }
 
-        return functionDetailsBuilder.build();
+        return 
FunctionConfigUtils.validateFunctionDetails(functionDetailsBuilder.build());
     }
 
     public static SourceConfig convertFromDetails(FunctionDetails 
functionDetails) {
diff --git 
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
 
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
index b2766b76146..389da88e583 100644
--- 
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
+++ 
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
@@ -45,6 +45,7 @@ import static 
org.apache.pulsar.common.functions.FunctionConfig.Runtime.PYTHON;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.assertTrue;
 
 /**
@@ -53,6 +54,18 @@ import static org.testng.Assert.assertTrue;
 @Slf4j
 public class FunctionConfigUtilsTest {
 
+    @Test
+    public void testAutoAckConvertFailed() {
+
+        FunctionConfig functionConfig = new FunctionConfig();
+        functionConfig.setAutoAck(false);
+        
functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATMOST_ONCE);
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            FunctionConfigUtils.convert(functionConfig, (ClassLoader) null);   
         
+        });
+    }
+
     @Test
     public void testConvertBackFidelity() {
         FunctionConfig functionConfig = new FunctionConfig();
@@ -128,6 +141,10 @@ public class FunctionConfigUtilsTest {
         Function.FunctionDetails functionDetails = 
FunctionConfigUtils.convert(functionConfig, (ClassLoader) null);
         FunctionConfig convertedConfig = 
FunctionConfigUtils.convertFromDetails(functionDetails);
 
+        // WindowsFunction guarantees convert to FunctionGuarantees.
+        
assertEquals(convertedConfig.getWindowConfig().getProcessingGuarantees(),
+                
WindowConfig.ProcessingGuarantees.valueOf(functionConfig.getProcessingGuarantees().name()));
+
         // add default resources
         functionConfig.setResources(Resources.getDefaultResources());
         // set default cleanupSubscription config
diff --git 
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
 
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
index 677cdb0343c..60f7d30052e 100644
--- 
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
+++ 
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
@@ -44,6 +44,7 @@ import static 
org.apache.pulsar.common.functions.FunctionConfig.ProcessingGuaran
 import static 
org.apache.pulsar.common.functions.FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.expectThrows;
 
@@ -60,6 +61,19 @@ public class SinkConfigUtilsTest {
         private String configParameter;
     }
 
+    @Test
+    public void testAutoAckConvertFailed() throws IOException {
+
+        SinkConfig sinkConfig = new SinkConfig();
+        sinkConfig.setAutoAck(false);
+        
sinkConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATMOST_ONCE);
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            SinkConfigUtils.convert(sinkConfig,
+                    new SinkConfigUtils.ExtractedSinkDetails(null, null));
+        });
+    }
+
     @Test
     public void testConvertBackFidelity() throws IOException  {
         SinkConfig sinkConfig = new SinkConfig();
diff --git 
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
 
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
index 306901d436e..420b7c113ca 100644
--- 
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
+++ 
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
@@ -1298,6 +1298,7 @@ public class FunctionApiV2ResourceTest {
                 .setName(function)
                 .setNamespace(namespace)
                 .setProcessingGuarantees(ProcessingGuarantees.ATMOST_ONCE)
+                .setAutoAck(true)
                 .setTenant(tenant)
                 .setParallelism(parallelism)
                 
.setSource(SourceSpec.newBuilder().setSubscriptionType(subscriptionType)
diff --git 
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
 
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
index 689e7ccbd48..a868d632506 100644
--- 
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
+++ 
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
@@ -1482,6 +1482,7 @@ public class FunctionApiV3ResourceTest {
         FunctionDetails functionDetails = FunctionDetails.newBuilder()
                 .setClassName(className)
                 .setSink(sinkSpec)
+                .setAutoAck(true)
                 .setName(function)
                 .setNamespace(namespace)
                 .setProcessingGuarantees(ProcessingGuarantees.ATMOST_ONCE)
diff --git a/site2/docs/functions-cli.md b/site2/docs/functions-cli.md
index 316266ab069..c2c4f3ee9fa 100644
--- a/site2/docs/functions-cli.md
+++ b/site2/docs/functions-cli.md
@@ -38,7 +38,7 @@ You can configure a function by using a predefined YAML file. 
The following tabl
 | outputSchemaType     | String                     | `-st`, `--schema-type`   
  | The built-in schema type or custom schema class name used for message 
outputs.   |
 | outputSerdeClassName | String                     | 
`--output-serde-classname` | The SerDe class used for message outputs. |
 | logTopic             | String                     | `--log-topic`            
  | The topic that the logs of a function are produced to.  |
-| processingGuarantees | String | `--processing-guarantees` | The processing 
guarantees (delivery semantics) applied to a function. Available values: 
`ATLEAST_ONCE`, `ATMOST_ONCE`, `EFFECTIVELY_ONCE`.|
+| processingGuarantees | String | `--processing-guarantees` | The processing 
guarantees (delivery semantics) applied to a function. Available values: 
`ATLEAST_ONCE`, `ATMOST_ONCE`, `EFFECTIVELY_ONCE`, `MANUAL`.|
 | retainOrdering       | Boolean                    | `--retain-ordering`      
     | Whether functions consume and process messages in order or not. |
 | retainKeyOrdering    | Boolean                    | `--retain-key-ordering`  
  | Whether functions consume and process messages in key order or not. |
 | batchBuilder         | String           | `--batch-builder` | Use 
`producerConfig.batchBuilder` instead. <br />**Note**: `batchBuilder` will be 
deprecated in code soon. |
@@ -46,7 +46,7 @@ You can configure a function by using a predefined YAML file. 
The following tabl
 | userConfig           | Map`<String,Object>`         | `--user-config`        
         | User-defined config key/values. |
 | secrets       | Map`<String,Object>` | `--secrets`   | The mapping from 
secretName to objects that encapsulate how the secret is fetched by the 
underlying secrets provider. |
 | runtime       | String             | N/A          | The runtime of a 
function. Available values: `java`,`python`, `go`. |
-| autoAck       | Boolean            | `--auto-ack` | Whether the framework 
acknowledges messages automatically or not. |
+| autoAck       | Boolean            | `--auto-ack` | Whether the framework 
acknowledges messages automatically or not. <br /><br />**Tip**: This 
configuration will be deprecated. If the user specifies delivery semantics, the 
framework will automatically ack messages. If you do not want the framework to 
ack messages, set the **processingGuarantees** to `MANUAL`. |
 | maxMessageRetries    | Int      |    `--max-message-retries` | The number of 
retries to process a message before giving up. |
 | deadLetterTopic      | String   | `--dead-letter-topic`   | The topic used 
for storing messages that are not processed successfully. |
 | subName              | String   | `--subs-name`           | The name of 
Pulsar source subscription used for input-topic consumers if required.|
diff --git a/site2/docs/functions-concepts.md b/site2/docs/functions-concepts.md
index a758ce45f2c..cfbba46aaf2 100644
--- a/site2/docs/functions-concepts.md
+++ b/site2/docs/functions-concepts.md
@@ -71,13 +71,15 @@ The following table outlines the three types of function 
runtime.
 
 ## Processing guarantees and subscription types
 
-Pulsar provides three different messaging delivery semantics that you can 
apply to a function. 
+Pulsar provides three different messaging delivery semantics that you can 
apply to a function. Different delivery semantic implementations are determined 
according to the **ack time node**.
 
 | Delivery semantics | Description | Adopted subscription type |
 |--------------------|-------------|---------------------------|
-| **At-most-once** delivery | Each message sent to a function is processed at 
its best effort. There’s no guarantee that the message will be processed or 
not. | Shared |
-| **At-least-once** delivery (default) | Each message sent to the function can 
be processed more than once (in case of a processing failure or redelivery).<br 
/><br />If you create a function without specifying the 
`--processing-guarantees` flag, the function provides `at-least-once` delivery 
guarantee. | Shared |
-| **Effectively-once** delivery | Each message sent to the function can be 
processed more than once but it has only one output. Duplicated messages are 
ignored.<br /><br />`Effectively once` is achieved on top of `at-least-once` 
processing and guaranteed server-side deduplication. This means a state update 
can happen twice, but the same state update is only applied once, the other 
duplicated state update is discarded on the server-side. | Failover |
+| **At-most-once** delivery | Each message sent to a function is processed at 
its best effort. There’s no guarantee that the message will be processed or 
not. <br /><br /> When setting At-most-once, the `autoAck` configuration must 
be equal to true, otherwise the startup will fail(`autoAck` configuration will 
be deprecated in future releases). <br/><br/> **Ack time node**: Before 
function processing. | Shared |
+| **At-least-once** delivery (default) | Each message sent to the function can 
be processed more than once (in case of a processing failure or redelivery).<br 
/><br />If you create a function without specifying the 
`--processing-guarantees` flag, the function provides `at-least-once` delivery 
guarantee. <br/><br/> **Ack time node**: After sending a message to output. | 
Shared |
+| **Effectively-once** delivery | Each message sent to the function can be 
processed more than once but it has only one output. Duplicated messages are 
ignored.<br /><br />`Effectively once` is achieved on top of `at-least-once` 
processing and guaranteed server-side deduplication. This means a state update 
can happen twice, but the same state update is only applied once, the other 
duplicated state update is discarded on the server-side. <br/><br/> **Ack time 
node**: After sending a messa [...]
+| **Manual** delivery | Under this semantics, the user needs to call the 
method `context.getCurrentRecord().ack()` inside the function to manually 
perform the ack operation, and the framework will not help users to do any ack 
operations. <br/><br/> **Ack time node**: User decides, in function method. | 
Shared |
+
 
 :::tip
 
@@ -167,6 +169,9 @@ Both processing time and event time are supported.
  * Processing time is defined based on the wall time when the function 
instance builds and processes a window. The judging of window completeness is 
straightforward and you don’t have to worry about data arrival disorder. 
  * Event time is defined based on the timestamps that come with the event 
record. It guarantees event time correctness but also offers more data 
buffering and a limited completeness guarantee.
 
+Delivery Semantic Guarantees.
+ * Currently, window function does not support `MANUAL` and  
`Effectively-once` delivery semantics.
+   
 :::
 
 ### Types of window

Reply via email to