From 72b661903e209c85db204db6f88e299e8244e898 Mon Sep 17 00:00:00 2001 From: "Mohamed S. Mahmoud" <mmahmoud@redhat.com> Date: Thu, 22 Aug 2024 12:14:03 -0400 Subject: [PATCH] DNS enhancement features [BP 1.6.2] (#394) * Allow DNS tracking to use configurable port for tracking Today DNS tracking uses only port 53 which is the port defined for DNS service and it get mapped to different port at the container level to avoid root access. This change wil allow tracking at the pod level as well Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com> (cherry picked from commit 45824ddde48cb5a93c47e706e4601f8468453ed8) * shrink dns port to u16 as that should be enough Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com> (cherry picked from commit fa535f2c3da2271478d80525e777ab094975888f) * Allow flow filtering for L4 protocols using two ports For example allow TCP ports="80,100" with por1 always < port2 Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com> (cherry picked from commit e68c3ba04e51bd8c89e94b20b50eb3abeb83774b) * Allow filtering with wildcard protocol field Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com> (cherry picked from commit b53ce35e0e596bdeecc2344b4c690fb91aec66c3) * Bump grpc to v1.65.0 Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com> --------- Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com> --- bpf/configs.h | 1 + bpf/dns_tracker.h | 5 +- bpf/flows_filter.h | 162 +- bpf/types.h | 6 + docs/flow_filtering.md | 7 +- go.mod | 19 +- go.sum | 45 +- pkg/agent/agent.go | 7 +- pkg/agent/config.go | 12 + pkg/agent/packets_agent.go | 6 +- pkg/ebpf/bpf_arm64_bpfel.go | 6 + pkg/ebpf/bpf_arm64_bpfel.o | Bin 119640 -> 125304 bytes pkg/ebpf/bpf_powerpc_bpfel.go | 6 + pkg/ebpf/bpf_powerpc_bpfel.o | Bin 118872 -> 124544 bytes pkg/ebpf/bpf_s390_bpfeb.go | 6 + pkg/ebpf/bpf_s390_bpfeb.o | Bin 134736 -> 140400 bytes pkg/ebpf/bpf_x86_bpfel.go | 6 + pkg/ebpf/bpf_x86_bpfel.o | Bin 119440 -> 125112 bytes pkg/ebpf/flow_filter.go | 79 +- pkg/ebpf/flow_filter_test.go | 55 +- pkg/ebpf/tracer.go | 9 + pkg/pbflow/flow_grpc.pb.go | 25 +- pkg/pbpacket/packet_grpc.pb.go | 25 +- vendor/github.com/cespare/xxhash/v2/README.md | 2 + vendor/github.com/cespare/xxhash/v2/xxhash.go | 29 +- .../cespare/xxhash/v2/xxhash_asm.go | 2 +- .../cespare/xxhash/v2/xxhash_other.go | 2 +- .../cespare/xxhash/v2/xxhash_safe.go | 2 +- .../cespare/xxhash/v2/xxhash_unsafe.go | 2 +- vendor/golang.org/x/net/html/doc.go | 2 +- .../golang.org/x/net/http/httpguts/httplex.go | 13 +- vendor/golang.org/x/net/http2/frame.go | 13 +- vendor/golang.org/x/net/http2/server.go | 11 +- vendor/golang.org/x/net/http2/transport.go | 15 +- .../x/oauth2/internal/client_appengine.go | 13 - .../golang.org/x/oauth2/internal/transport.go | 5 - vendor/golang.org/x/oauth2/oauth2.go | 2 +- vendor/google.golang.org/appengine/LICENSE | 202 - .../appengine/internal/api.go | 653 --- .../appengine/internal/api_classic.go | 170 - .../appengine/internal/api_common.go | 141 - .../appengine/internal/app_id.go | 28 - .../appengine/internal/base/api_base.pb.go | 308 -- .../appengine/internal/base/api_base.proto | 33 - .../internal/datastore/datastore_v3.pb.go | 4367 ----------------- .../internal/datastore/datastore_v3.proto | 551 --- .../appengine/internal/identity.go | 54 - .../appengine/internal/identity_classic.go | 62 - .../appengine/internal/identity_flex.go | 12 - .../appengine/internal/identity_vm.go | 134 - .../appengine/internal/internal.go | 110 - .../appengine/internal/log/log_service.pb.go | 1313 ----- .../appengine/internal/log/log_service.proto | 150 - .../appengine/internal/main.go | 17 - .../appengine/internal/main_common.go | 7 - .../appengine/internal/main_vm.go | 70 - .../appengine/internal/metadata.go | 60 - .../appengine/internal/net.go | 56 - .../appengine/internal/regen.sh | 40 - .../internal/remote_api/remote_api.pb.go | 361 -- .../internal/remote_api/remote_api.proto | 44 - .../appengine/internal/transaction.go | 115 - .../internal/urlfetch/urlfetch_service.pb.go | 527 -- .../internal/urlfetch/urlfetch_service.proto | 64 - .../appengine/urlfetch/urlfetch.go | 209 - .../googleapis/api/httpbody/httpbody.pb.go | 4 +- .../rpc/errdetails/error_details.pb.go | 4 +- .../googleapis/rpc/status/status.pb.go | 4 +- vendor/google.golang.org/grpc/CONTRIBUTING.md | 2 +- vendor/google.golang.org/grpc/MAINTAINERS.md | 1 + vendor/google.golang.org/grpc/Makefile | 7 +- vendor/google.golang.org/grpc/README.md | 2 +- .../{ => balancer/pickfirst}/pickfirst.go | 70 +- .../grpc/balancer/roundrobin/roundrobin.go | 4 +- .../grpc/balancer_wrapper.go | 4 + .../grpc_binarylog_v1/binarylog.pb.go | 2 +- vendor/google.golang.org/grpc/clientconn.go | 96 +- vendor/google.golang.org/grpc/codegen.sh | 17 - vendor/google.golang.org/grpc/codes/codes.go | 2 +- .../grpc/credentials/credentials.go | 6 +- .../google.golang.org/grpc/credentials/tls.go | 34 +- vendor/google.golang.org/grpc/dialoptions.go | 82 +- .../grpc/health/grpc_health_v1/health.pb.go | 2 +- .../health/grpc_health_v1/health_grpc.pb.go | 24 +- .../grpc/internal/backoff/backoff.go | 4 +- .../balancer/gracefulswitch/config.go | 1 - .../balancer/gracefulswitch/gracefulswitch.go | 1 - .../grpc/internal/binarylog/method_logger.go | 6 +- .../grpc/internal/envconfig/envconfig.go | 9 +- .../grpc/internal/grpcrand/grpcrand.go | 100 - .../grpc/internal/grpcrand/grpcrand_go1.21.go | 73 - .../grpc/internal/grpcutil/compressor.go | 5 - .../grpc/internal/internal.go | 37 +- .../internal/resolver/dns/dns_resolver.go | 40 +- .../resolver/dns/internal/internal.go | 19 +- .../grpc/internal/transport/controlbuf.go | 33 +- .../grpc/internal/transport/http2_client.go | 68 +- .../grpc/internal/transport/http2_server.go | 16 +- .../grpc/internal/transport/transport.go | 2 +- vendor/google.golang.org/grpc/peer/peer.go | 30 + .../google.golang.org/grpc/picker_wrapper.go | 84 +- .../grpc/reflection/adapt.go | 138 +- .../grpc_reflection_v1/reflection.pb.go | 2 +- .../grpc_reflection_v1/reflection_grpc.pb.go | 13 +- .../grpc_reflection_v1alpha/reflection.pb.go | 2 +- .../reflection_grpc.pb.go | 13 +- .../grpc/reflection/internal/internal.go | 436 ++ .../grpc/reflection/serverreflection.go | 210 +- vendor/google.golang.org/grpc/regenerate.sh | 6 +- .../grpc/resolver/dns/dns_resolver.go | 12 +- .../grpc/resolver_wrapper.go | 2 +- vendor/google.golang.org/grpc/rpc_util.go | 3 +- vendor/google.golang.org/grpc/server.go | 16 +- .../google.golang.org/grpc/service_config.go | 32 +- vendor/google.golang.org/grpc/stats/stats.go | 10 +- vendor/google.golang.org/grpc/stream.go | 5 +- .../grpc/stream_interfaces.go | 152 + vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 195 - vendor/modules.txt | 36 +- 120 files changed, 1515 insertions(+), 11123 deletions(-) delete mode 100644 vendor/golang.org/x/oauth2/internal/client_appengine.go delete mode 100644 vendor/google.golang.org/appengine/LICENSE delete mode 100644 vendor/google.golang.org/appengine/internal/api.go delete mode 100644 vendor/google.golang.org/appengine/internal/api_classic.go delete mode 100644 vendor/google.golang.org/appengine/internal/api_common.go delete mode 100644 vendor/google.golang.org/appengine/internal/app_id.go delete mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.proto delete mode 100644 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto delete mode 100644 vendor/google.golang.org/appengine/internal/identity.go delete mode 100644 vendor/google.golang.org/appengine/internal/identity_classic.go delete mode 100644 vendor/google.golang.org/appengine/internal/identity_flex.go delete mode 100644 vendor/google.golang.org/appengine/internal/identity_vm.go delete mode 100644 vendor/google.golang.org/appengine/internal/internal.go delete mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.proto delete mode 100644 vendor/google.golang.org/appengine/internal/main.go delete mode 100644 vendor/google.golang.org/appengine/internal/main_common.go delete mode 100644 vendor/google.golang.org/appengine/internal/main_vm.go delete mode 100644 vendor/google.golang.org/appengine/internal/metadata.go delete mode 100644 vendor/google.golang.org/appengine/internal/net.go delete mode 100644 vendor/google.golang.org/appengine/internal/regen.sh delete mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto delete mode 100644 vendor/google.golang.org/appengine/internal/transaction.go delete mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto delete mode 100644 vendor/google.golang.org/appengine/urlfetch/urlfetch.go rename vendor/google.golang.org/grpc/{ => balancer/pickfirst}/pickfirst.go (74%) delete mode 100644 vendor/google.golang.org/grpc/codegen.sh delete mode 100644 vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go create mode 100644 vendor/google.golang.org/grpc/reflection/internal/internal.go create mode 100644 vendor/google.golang.org/grpc/stream_interfaces.go delete mode 100644 vendor/google.golang.org/grpc/vet.sh diff --git a/bpf/configs.h b/bpf/configs.h index 397d7548..38cb325e 100644 --- a/bpf/configs.h +++ b/bpf/configs.h @@ -9,4 +9,5 @@ volatile const u8 enable_rtt = 0; volatile const u8 enable_pca = 0; volatile const u8 enable_dns_tracking = 0; volatile const u8 enable_flows_filtering = 0; +volatile const u16 dns_port = 0; #endif //__CONFIGS_H__ diff --git a/bpf/dns_tracker.h b/bpf/dns_tracker.h index a2253fa8..714e1286 100644 --- a/bpf/dns_tracker.h +++ b/bpf/dns_tracker.h @@ -6,10 +6,10 @@ #define __DNS_TRACKER_H__ #include "utils.h" -#define DNS_PORT 53 #define DNS_QR_FLAG 0x8000 #define UDP_MAXMSG 512 #define EINVAL 22 +#define DNS_DEFAULT_PORT 53 struct dns_header { u16 id; @@ -67,7 +67,8 @@ static __always_inline u8 calc_dns_header_offset(pkt_info *pkt, void *data_end) static __always_inline int track_dns_packet(struct __sk_buff *skb, pkt_info *pkt) { void *data_end = (void *)(long)skb->data_end; - if (pkt->id->dst_port == DNS_PORT || pkt->id->src_port == DNS_PORT) { + if (pkt->id->dst_port == dns_port || pkt->id->src_port == dns_port || + pkt->id->dst_port == DNS_DEFAULT_PORT || pkt->id->src_port == DNS_DEFAULT_PORT) { dns_flow_id dns_req; u8 len = calc_dns_header_offset(pkt, data_end); diff --git a/bpf/flows_filter.h b/bpf/flows_filter.h index 3f420414..2deee61e 100644 --- a/bpf/flows_filter.h +++ b/bpf/flows_filter.h @@ -49,98 +49,96 @@ static __always_inline int do_flow_filter_lookup(flow_id *id, struct filter_key_ *action = rule->action; result++; } - - if (rule->protocol != 0) { - if (rule->protocol == id->transport_protocol) { - BPF_PRINTK("protocol matched\n"); - result++; - switch (rule->protocol) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_SCTP: - // dstPort matching - if (rule->dstPortStart != 0 && rule->dstPortEnd == 0) { - if (rule->dstPortStart == id->dst_port) { - BPF_PRINTK("dstPortStart matched\n"); - result++; - } else { - result = 0; - goto end; - } - } else if (rule->dstPortStart != 0 && rule->dstPortEnd != 0) { - if (rule->dstPortStart <= id->dst_port && - id->dst_port <= rule->dstPortEnd) { - BPF_PRINTK("dstPortStart and dstPortEnd matched\n"); - result++; - } else { - result = 0; - goto end; - } + // match specific rule protocol or use wildcard protocol + if (rule->protocol == id->transport_protocol || rule->protocol == 0) { + switch (id->transport_protocol) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_SCTP: + // dstPort matching + if ((rule->dstPortStart != 0 && rule->dstPortEnd == 0) || rule->dstPort1 != 0 || + rule->dstPort2 != 0) { + if (rule->dstPortStart == id->dst_port || rule->dstPort1 == id->dst_port || + rule->dstPort2 == id->dst_port) { + BPF_PRINTK("dstPort matched\n"); + result++; + } else { + result = 0; + goto end; } - // srcPort matching - if (rule->srcPortStart != 0 && rule->srcPortEnd == 0) { - if (rule->srcPortStart == id->src_port) { - BPF_PRINTK("srcPortStart matched\n"); - result++; - } else { - result = 0; - goto end; - } - } else if (rule->srcPortStart != 0 && rule->srcPortEnd != 0) { - if (rule->srcPortStart <= id->src_port && - id->src_port <= rule->srcPortEnd) { - BPF_PRINTK("srcPortStart and srcPortEnd matched\n"); - result++; - } else { - result = 0; - goto end; - } + } else if (rule->dstPortStart != 0 && rule->dstPortEnd != 0) { + if (rule->dstPortStart <= id->dst_port && id->dst_port <= rule->dstPortEnd) { + BPF_PRINTK("dstPortStart and dstPortEnd matched\n"); + result++; + } else { + result = 0; + goto end; } - // Generic port matching check for either src or dst port - if (rule->portStart != 0 && rule->portEnd == 0) { - if (rule->portStart == id->src_port || rule->portStart == id->dst_port) { - BPF_PRINTK("portStart matched\n"); - result++; - } else { - result = 0; - goto end; - } - } else if (rule->portStart != 0 && rule->portEnd != 0) { - if ((rule->portStart <= id->src_port && id->src_port <= rule->portEnd) || - (rule->portStart <= id->dst_port && id->dst_port <= rule->portEnd)) { - BPF_PRINTK("portStart and portEnd matched\n"); - result++; - } else { - result = 0; - goto end; - } + } + // srcPort matching + if ((rule->srcPortStart != 0 && rule->srcPortEnd == 0) || rule->srcPort1 != 0 || + rule->srcPort2 != 0) { + if (rule->srcPortStart == id->src_port || rule->srcPort1 == id->src_port || + rule->srcPort2 == id->src_port) { + BPF_PRINTK("srcPort matched\n"); + result++; + } else { + result = 0; + goto end; } - break; - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - if (rule->icmpType != 0) { - if (rule->icmpType == id->icmp_type) { - BPF_PRINTK("icmpType matched\n"); + } else if (rule->srcPortStart != 0 && rule->srcPortEnd != 0) { + if (rule->srcPortStart <= id->src_port && id->src_port <= rule->srcPortEnd) { + BPF_PRINTK("srcPortStart and srcPortEnd matched\n"); + result++; + } else { + result = 0; + goto end; + } + } + // Generic port matching check for either src or dst port + if ((rule->portStart != 0 && rule->portEnd == 0) || rule->port1 != 0 || + rule->port2 != 0) { + if (rule->portStart == id->src_port || rule->portStart == id->dst_port || + rule->port1 == id->src_port || rule->port1 == id->dst_port || + rule->port2 == id->src_port || rule->port2 == id->dst_port) { + BPF_PRINTK("port matched\n"); + result++; + } else { + result = 0; + goto end; + } + } else if (rule->portStart != 0 && rule->portEnd != 0) { + if ((rule->portStart <= id->src_port && id->src_port <= rule->portEnd) || + (rule->portStart <= id->dst_port && id->dst_port <= rule->portEnd)) { + BPF_PRINTK("portStart and portEnd matched\n"); + result++; + } else { + result = 0; + goto end; + } + } + break; + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + if (rule->icmpType != 0) { + if (rule->icmpType == id->icmp_type) { + BPF_PRINTK("icmpType matched\n"); + result++; + } else { + result = 0; + goto end; + } + if (rule->icmpCode != 0) { + if (rule->icmpCode == id->icmp_code) { + BPF_PRINTK("icmpCode matched\n"); result++; } else { result = 0; goto end; } - if (rule->icmpCode != 0) { - if (rule->icmpCode == id->icmp_code) { - BPF_PRINTK("icmpCode matched\n"); - result++; - } else { - result = 0; - goto end; - } - } } - break; } - } else { - result = 0; - goto end; + break; } } diff --git a/bpf/types.h b/bpf/types.h index c6df9b1e..3f96244b 100644 --- a/bpf/types.h +++ b/bpf/types.h @@ -208,10 +208,16 @@ struct filter_value_t { u8 protocol; u16 dstPortStart; u16 dstPortEnd; + u16 dstPort1; + u16 dstPort2; u16 srcPortStart; u16 srcPortEnd; + u16 srcPort1; + u16 srcPort2; u16 portStart; u16 portEnd; + u16 port1; + u16 port2; u8 icmpType; u8 icmpCode; direction direction; diff --git a/docs/flow_filtering.md b/docs/flow_filtering.md index 50ef5821..18509efc 100644 --- a/docs/flow_filtering.md +++ b/docs/flow_filtering.md @@ -24,10 +24,13 @@ Rule-base filtering is a method to control the flow of packets cached in the eBP - `FILTER_PROTOCOL` - Protocol of the flow filter rule. Possible values are `TCP`, `UDP`, `SCTP`, `ICMP`, `ICMPv6`. - `FILTER_SOURCE_PORT` - Single Source port of the flow filter rule. - `FILTER_SOURCE_PORT_RANGE` - Source port range of the flow filter rule. using "80-100" format. +- `FILTER_SOURCE_PORTS` - Source port two values of the flow filter rule. using "80,100" format. - `FILTER_DESTINATION_PORT` - Single Destination port of the flow filter rule. - `FILTER_DESTINATION_PORT_RANGE` - Destination port range of the flow filter rule. using "80-100" format. -- `FILTER_PORT` - Single L4 port of the flow filter rule, can be either source or destination port. -- `FILTER_PORT_RANGE` - L4 port range of the flow filter rule. using "80-100" format can be either source or destination ports range. +- `FILTER_DESTINATION_PORTS` - Destination port two values of the flow filter rule. using "80,100" format. +- `FILTER_PORT` - Single L4 port of the flow filter rule can be either source or destination port. +- `FILTER_PORT_RANGE` - L4 port range of the flow filter rule. using "80–100" format can be either a source or destination ports range. +- `FILTER_PORTS` - Two ports values of the flow filter rule. using "80,100" format can be either two ports for src or two ports for destination. - `FILTER_ICMP_TYPE` - ICMP type of the flow filter rule. - `FILTER_ICMP_CODE` - ICMP code of the flow filter rule. - `FILTER_PEER_IP` - Specific Peer IP address of the flow filter rule. diff --git a/go.mod b/go.mod index 3ac7584f..1b7a74bc 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/vladimirvivien/gexe v0.3.0 github.com/vmware/go-ipfix v0.9.0 golang.org/x/sys v0.21.0 - google.golang.org/grpc v1.63.2 + google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.30.2 @@ -40,7 +40,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect @@ -113,16 +113,15 @@ require ( go.opentelemetry.io/otel/trace v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.9.0 // indirect - golang.org/x/crypto v0.22.0 // indirect + golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index b14388e2..8cdd0362 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -362,8 +362,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -951,8 +949,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1040,8 +1038,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1049,8 +1047,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1066,8 +1064,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1152,8 +1150,8 @@ golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1167,8 +1165,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1281,8 +1279,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1317,10 +1313,10 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1340,8 +1336,8 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1353,7 +1349,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index d8e23671..72c4babc 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -185,6 +185,7 @@ func FlowsAgent(cfg *Config) (*Flows, error) { CacheMaxSize: cfg.CacheMaxFlows, PktDrops: cfg.EnablePktDrops, DNSTracker: cfg.EnableDNSTracking, + DNSTrackerPort: cfg.DNSTrackingPort, EnableRTT: cfg.EnableRTT, EnableFlowFilter: cfg.EnableFlowFilter, FilterConfig: &ebpf.FilterConfig{ @@ -193,9 +194,9 @@ func FlowsAgent(cfg *Config) (*Flows, error) { FilterIPCIDR: cfg.FilterIPCIDR, FilterProtocol: cfg.FilterProtocol, FilterPeerIP: cfg.FilterPeerIP, - FilterDestinationPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterDestinationPort, cfg.FilterDestinationPortRange), - FilterSourcePort: ebpf.ConvertFilterPortsToInstr(cfg.FilterSourcePort, cfg.FilterSourcePortRange), - FilterPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterPort, cfg.FilterPortRange), + FilterDestinationPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterDestinationPort, cfg.FilterDestinationPortRange, cfg.FilterDestinationPorts), + FilterSourcePort: ebpf.ConvertFilterPortsToInstr(cfg.FilterSourcePort, cfg.FilterSourcePortRange, cfg.FilterSourcePorts), + FilterPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterPort, cfg.FilterPortRange, cfg.FilterPorts), }, } diff --git a/pkg/agent/config.go b/pkg/agent/config.go index 5793c259..aec707a7 100644 --- a/pkg/agent/config.go +++ b/pkg/agent/config.go @@ -161,6 +161,9 @@ type Config struct { EnablePktDrops bool `env:"ENABLE_PKT_DROPS" envDefault:"false"` // EnableDNSTracking enable DNS tracking eBPF hook to track dns query/response flows EnableDNSTracking bool `env:"ENABLE_DNS_TRACKING" envDefault:"false"` + // DNSTrackingPort used to define which port the DNS service is mapped to at the pod level, + // so we can track DNS at the pod level + DNSTrackingPort uint16 `env:"DNS_TRACKING_PORT" envDefault:"53"` // StaleEntriesEvictTimeout specifies the maximum duration that stale entries are kept // before being deleted, default is 5 seconds. StaleEntriesEvictTimeout time.Duration `env:"STALE_ENTRIES_EVICT_TIMEOUT" envDefault:"5s"` @@ -199,12 +202,21 @@ type Config struct { // FilterSourcePortRange is the source port range to filter flows. // Example: 8000-8010 FilterSourcePortRange string `env:"FILTER_SOURCE_PORT_RANGE"` + // FilterSourcePorts is two source ports to filter flows. + // Example: 8000,8010 + FilterSourcePorts string `env:"FILTER_SOURCE_PORTS"` // FilterDestinationPortRange is the destination port range to filter flows. // Example: 8000-8010 FilterDestinationPortRange string `env:"FILTER_DESTINATION_PORT_RANGE"` + // FilterDestinationPorts is two destination ports to filter flows. + // Example: 8000,8010 + FilterDestinationPorts string `env:"FILTER_DESTINATION_PORTS"` // FilterPortRange is the port range to filter flows, can be used for either source or destination port. // Example: 8000-8010 FilterPortRange string `env:"FILTER_PORT_RANGE"` + // FilterPorts is two ports option to filter flows, can be used for either source or destination port. + // Example: 8000,8010 + FilterPorts string `env:"FILTER_PORTS"` // FilterICMPType is the ICMP type to filter flows. FilterICMPType int `env:"FILTER_ICMP_TYPE"` // FilterICMPCode is the ICMP code to filter flows. diff --git a/pkg/agent/packets_agent.go b/pkg/agent/packets_agent.go index 87e1ab03..1b1ad4b2 100644 --- a/pkg/agent/packets_agent.go +++ b/pkg/agent/packets_agent.go @@ -86,9 +86,9 @@ func PacketsAgent(cfg *Config) (*Packets, error) { FilterIPCIDR: cfg.FilterIPCIDR, FilterProtocol: cfg.FilterProtocol, FilterPeerIP: cfg.FilterPeerIP, - FilterDestinationPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterDestinationPort, cfg.FilterDestinationPortRange), - FilterSourcePort: ebpf.ConvertFilterPortsToInstr(cfg.FilterSourcePort, cfg.FilterSourcePortRange), - FilterPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterPort, cfg.FilterPortRange), + FilterDestinationPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterDestinationPort, cfg.FilterDestinationPortRange, cfg.FilterDestinationPorts), + FilterSourcePort: ebpf.ConvertFilterPortsToInstr(cfg.FilterSourcePort, cfg.FilterSourcePortRange, cfg.FilterSourcePorts), + FilterPort: ebpf.ConvertFilterPortsToInstr(cfg.FilterPort, cfg.FilterPortRange, cfg.FilterPorts), }, } diff --git a/pkg/ebpf/bpf_arm64_bpfel.go b/pkg/ebpf/bpf_arm64_bpfel.go index e13c50b9..ecb509e7 100644 --- a/pkg/ebpf/bpf_arm64_bpfel.go +++ b/pkg/ebpf/bpf_arm64_bpfel.go @@ -53,10 +53,16 @@ type BpfFilterValueT struct { Protocol uint8 DstPortStart uint16 DstPortEnd uint16 + DstPort1 uint16 + DstPort2 uint16 SrcPortStart uint16 SrcPortEnd uint16 + SrcPort1 uint16 + SrcPort2 uint16 PortStart uint16 PortEnd uint16 + Port1 uint16 + Port2 uint16 IcmpType uint8 IcmpCode uint8 Direction BpfDirectionT diff --git a/pkg/ebpf/bpf_arm64_bpfel.o b/pkg/ebpf/bpf_arm64_bpfel.o index 3141e95644865092590d028d5d562f4c2377c7ab..e188a8b9cebac2aeb66c41968c8493357cb62563 100644 GIT binary patch delta 48870 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 delta 43405 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 S>spb<_7;Q2`k*>tgQ);$Z6oXe diff --git a/pkg/ebpf/bpf_powerpc_bpfel.go b/pkg/ebpf/bpf_powerpc_bpfel.go index 3535af8f..daa4d59d 100644 --- a/pkg/ebpf/bpf_powerpc_bpfel.go +++ b/pkg/ebpf/bpf_powerpc_bpfel.go @@ -53,10 +53,16 @@ type BpfFilterValueT struct { Protocol uint8 DstPortStart uint16 DstPortEnd uint16 + DstPort1 uint16 + DstPort2 uint16 SrcPortStart uint16 SrcPortEnd uint16 + SrcPort1 uint16 + SrcPort2 uint16 PortStart uint16 PortEnd uint16 + Port1 uint16 + Port2 uint16 IcmpType uint8 IcmpCode uint8 Direction BpfDirectionT diff --git a/pkg/ebpf/bpf_powerpc_bpfel.o b/pkg/ebpf/bpf_powerpc_bpfel.o index c9f16da10ebe1901b7cdce2166395a331a6a73de..19dc48bb5a9d5152f929e5e5240d88e45feeb40c 100644 GIT binary patch delta 48494 zcmcbyfW6@?`veW9hPxZJtQeUhIVYzv#xcI%e3Y@CiSh4bSC(+bDU;{2nAXo{0D;OC zJN|>{!X_gS#gNX#z`()4z);v|2<H0>fhmT>!~ifuf(1;$iA-k*Q`QKii-DoARUa%+ z*lYl%)0rXW`3Hl!44EzvS~QZGiNTbCfkBjs5lqKA_kv{#n~cG<C{q)IAOizKC{rf` z8v_GF<>Cuqhl(<{gXQ-_+{?hu#K0iJz`&p@)B+aIG@4w+D$i)Nc^2z_W=psxkP!?F z$eKXz)fHj}YuXO=b*3T2d#a3^CvnbTWo(?R&F{##XmT$9RHn3llm7_GY*r8mVq%g2 zvE{f~!I~u)85nj=o-0)A#QYB=0ODT&F`yV^ILN213=CkOurmDn3zFK-$iTqJz`$@= z0K{WpU}gCIcXN#JIxfbgo4MuunVB@1C&wt3F`Z=Ed__@>$x#5Lm|;JdWMC*1QUGg% zN0_iYnC}k_mqKAhFdq~FAPWk`l_p!OnAN91g11l<EXyFu$^>S>LMGPrAef)Z!omR3 zCd#4>b|g$*l!X=Qi9KL-qAbh|pnw-;QDd-TK!k88%MNh#6^cOITPOsvryk~Be<!eh z22mzRC>Dx9qM}d~5(Vk3(1ha(RmaK&W)zA*)r&%+6kS~?D^y;D9im<o6wwR}P<8bT z{%`~3APQ0;DZMZS5_0J*P>Vyr(hRarP>Y422BTZ73RUL{l^4QlF@rx?T|EOstm{Rv z4ps&wFkL7j38oQ2JQ2(<Ofmt}u_~v*G)x|p;z5C0C?W+G7iH-N(}hW(RK~y%t8x^~ zXJ=+$00lZsA1gx}14BJH%YiZs14E%GG{{AuL5}8gQ5Jr%LDgO-z*(;l8dB9!kgSLv zV%1(Z!0IZOLgXu#K=}U9kOawt>}RN43X#wa+5onoauLJ=UDb79KFH-@9}01T`Gq2o zD1b+e3Rsu{lo&y*LLqJt#ZV~91E!&I4GnSz22ohr5#j~g&rm4JhgBgw@d!bDUMLF6 z1MtLyWFSPmFcn(bB|%F&XgT5^1U8;QRt4hlLJ?lDK%r<on#It>D60xhJR&$OhN_EI z?E)Lb${+@&VR0+U0^t)1iT(AEM9v_}3h_a86eQ>ilOR5+)`G-cA)1e>wIESexd<W; zi$X}MW?-m}g2_W@U6oR>11pz6%-3})2J`D-aSL;Kp$MpyXJ9B4hSW5m@(Pq={h<|$ zC^IZ%guw<Bib4`EJdU9u1CL`7NXb?x3JDQ3bvg|2I2I9y8Yls#(G)U>vi_WGtfpEo z>nshHN2Gp;538*pAyJqN2~wED;UNR9@%BS<CA<QIg_LYCBnAqFAr6L{Ck%Bsq~@$= zfMq9G6)Nit$rUh*WP@P^4%9=!P!B;2U_j^tl?Dt9uxuIYYzy`ntUTEcDGeAvrYSRk z>LZZ)&1xDpjD|8`l`t<Bia>${7Dt65vJiO|25_ZOC@431vSv8r;>oWy%^BxxR@PEy za?}9jXhiiT46VMPjw}>{R$m~SLG2F_X!Qj%Qb=iXw~ia(>gy`lC4{RlNDYm<`Z_b{ zt1k<%PhrUty)cFqx-_W1o`WrBWv~I$nAO)(h&a6ZdI;vjGCVA~A*wG(OB7Lk-3F@% z6%?QZ2-C;PFbi6JF{^{CnL<%$i68<k5iqJRC9pbBwF5G-Fa=t~c|kL7Dzwmswlpf2 zK*V7U1Xw=N4F;!N2HOx$hRJ)>P3jR6K41%UUA@6HD+4c>7G;7sh(`4*qC|i>1QypY zpTbH8-Jmrfk24_Z*HvIXC}=@`DkQ6Zt;bd$LhCspSUrbU&4JrK42ZIqlKK@?h2ySZ z(JY464#d~5ZQu~XSHFVn$Jx|?rB)i&ul3+WrmIp2b}6EQ%?I;gaSL+@_3KwpNPUH) zf<?qJ!TQw-RKN1bIz!B>o^|8@<TLs@^|HZ`I4qQeNED)0hz$Od!5(F(TnVX&Wt~Co z1qKFqJt&Ez9>mZG$^#4xvBCCW1EB?z3Iq0vkbwafw6@K`lZ_418C@sOHn3+@nS9$o z-4jyfiZVX{M-Jhl={8s$$j>0V3o{`_Q(>yX<lFl4lMm@zK%2C>u8^F?%5ducW)?#^ zcvTE7><WdURWYQmz)&a(t%_NpRk5(#=3paFJ|>gjo98)vV`6OEJk>d$kuha6t82P2 zQ!xAHyofwzM)}Qmqwg~@N^IU6cb=KiVRCO$J5w+FWU=Hp)?Ri7hV7FdCJS%wN!Dka zyd&l7<PE8JxC#Op7(lqSeDkz4FE&;o1_l=6$xm~P>o+hlFo0qZR6p&6vOO3W7>+^N z5ey6r7oqG71_p*(P<90a1H)q|yMuv&;VqOsgMoqJE0n#0fq~&Sl)Zz2fq{{k0bEa? zU|?Y2g0SluKvjDf0|SE{0|Ubi1_lOUW(Eca1_p*73=9lX%nS^mWCiM^gVZoEFmQmP zUzVAHfti7U4b&6Tgf@f>nIRo?3us5m4I<9r$iTo5f}}nLBF>NvR?p19P&D~su0Lbz zWW_vb)d?U|85meV&7D=u3=D3d_-0^WSjWu3;LZSX*tW@udE%1$nHd;B;q(9$R?G|x zULci>3=C%{Ps~&1y~)hL0IKgm3GMmhgL&fhubCMb0-#R*4Rr!P3&hDXERepR6${u~ z3?VEG3?Q!+v4Glj3=G{Ykg<rBEDYfG-XUmmddR}S0BT+SW?^6eB|KqP1_n^yN{5w! z0o1qhU}azc74ZeE4E5kh?qOwM0CicGL(|(aR!D?AU}azcH|W_Q&Q@ZB4AVHWLBc<Q zjRD++sbXVb0A<&iYzzz_uWe&vU;uT8ud*>PfV#Jz*ccc<DO{MHfdSMAHDPC90HyFq z_Id^ePzS!4oq++=bezo2zyJ#4wd@QGpr+#~b_Q_&`WZU|1E@{O#=*b<>NaX|Fff2> zBR>uX1~mo-hHMT726YAohAs{U1`P%VhBX`v44MoK3@14l7_=A|7+!HOFlaL{FtBqn zFz7HaFsO4fFz7NcFgVq7GBD^dFfhb$GBAL0Z#gFe1E@hUnUjG5G@`JalYs%$GdRS_ zzyKO^dBn-U0LrAlIT^qMUgBH~3}y@r4CY)64CV|B4E|gU44^EN$;H56$-uzS%*6m6 zQJKlbz+lb5z_6K%0o>v`$Hl+^YPi?G=7J<~R&E9cP!d+=hNLEEZUzQW5>4c0U;quW z)N(U0fI3stxEUBgqi;L885ls-;x%qaYW&CzNr{3yko0HB!@%Ilz`zj314)BbJPZup z3=9klc^DXcKq14!z~Bpt)u%iR41Np@3_n3BgW>;wQQpaEg+^jhybycjdBJIs2c%b) zZ}PfAJtkGY$@dDy>NWTn7(l%v2WAEaJw8apH!w3W7(v+!m>C$X`5+1F05b!FGn9RS znSsF@%6`Diz!1sDz>v<s!0>^YfgzI*lHfitGcXoF*&mr17|WpSPs|KVwGg%z!xv@- z#uf;N;VUx(V;_|LjhTUQCY1f1nSpW1<he!Sp4<2s7-|_97!I&9Fzkl1LFs!x9|J=j zD3h`=FdTuh9oQHcPC~uWz{bFEi4W3fUBJe`aAWe{B4yjhd<+cG0TG5*d<+cGQi$O_ z9|HrZXapGu!psZ|ETA0moe!MNK|&0FCdU@**E8}nFhB<w7+CosK?#<I5KOlj85jgX znUaBl5mYsT%0791a6tezQ5{K-B|ig0D6|-Ig0dSR=72~hkW0Pz!G#G6sK5H1k3o+i z93;iS!0?BU0n7$j02N{ac_)M)9P=z7%fC;yEK%l-=VxGuhAK&#oLQo5Tg=bE5DOKl z;%8t;gt9vz4(EttU|^U4WydoxFie566Brm6W=%d>;?28+9}#%lCo7hU^BzR<*xAXh zrO}KxCNC@%uYbS~NhcsHKJi1+2?GNI^KU2{RBnUDLqG)<r~s7|fT&?*U|>>)ve_9J z7<B|7=79WV3l-;JU|<Y@vN;(T7~`O9E(Qk1d<eT9RD?3tLpY#flyL%-&C9^RG#knW zh1q&2TY!OqaXXYP$iTq3AIcVDU|_reWeYPfFy4l;MHm<uA3@oo3=E7PplmS)2FCva z?hxOIGcYi62}0Ns3=B+?P_`5U1EUI*EzQ8dXbfe`FfcIM2tslpsAP4W{I^V8(q9l# zV1wczLJ*uV7(fXoVX|(yGGprGz;b2DT&S)9Mh1o!C_90Xfnnz4-g0rtRZx)$j0_CB zq3i{W3=F3x?=4qmygK<|xj54;!O4CVV!RKb(x8ZYGg-DmobktG(+YhlMj-|UNb{G0 zfkz19L{RD!6`EXEA!aBe1SwNM+EkF(AU+cV11qQ|)E9#I10-fL`EIp%y&ICDp+b;w z0?C4~4g*6AsBorXN~#CVyAVoBG)zhL5Fg`DN)R;^rzAlJhAak1bqNaHGEe~os@-uX zuF@({;+k1SAaNPuOkB{Ev;orQ2Mvsalfl)=ven91(^+b@G9PL>n=D6e+LFYTwvs3F z)`;5{feIc51`bd@ss-h71_l;T8toNgU}yvd5Ca3lB&eDuD4!9kX7=R78sYj6j0_B+ z!VC;?3=Azlm>3wMgc%q>^GzVdX~GN)pmwtZ3j;%eFf_-qFfcR;GcbVqj0;#87$yrd zFsuYsaV!iBvxOnHf~vbEQ1zhdZi6rb!*-B?Yzz$hq3i=}3=9{98R{8!GcYhTurn~+ zhH7x&U|@IywIG3mf#HuZBuh4MFfg!-K-dd77#M^^APzdf!N4E`Wj_ElxkMNkz%xvs z)+hr5!(LDl0kxb&7#JRb?BZl#uor=NjDf43fx$-v;%Wyj28Jl8K?z(83@K1{0~Z5B zu?Vy>=3-!I6oFKn2SCkSP|pM8Gj0ZkJ`sp79k>}7=87;dJOzpKFfgoynxnwOz_3dM zQg%4-Ffd#cVPMDy4GARhFfcq4VPJR$avcu?!#fcM22i);01pGhcc=zXlbKl*qFI5D zfq`2T;s^&m1_mi8yMd2^L06Q40W`{XfRBN}RFr|?CCK;u3=E*IGH6V!fuDiFUlbaO z{0t2B@uCb2uR!s~&%lriwE$FBm5VYkYzFy2fPt|c%4QT`V4MPFGYK#-E{3w11sE7N zLD?(<3@rPhYz_eihV!D394jEez;GSPRuEudcno3JGZ+XkFnoskzyVZ!i7_xt0fmGB z1B0L#0|RJQ@qhpWgOV5|zCpb<O(<JIkb%Ke43Zcf1Q{4ypzH)e28M7k28P!la|9U} z;=~}HSpX_NpzIZb3=DN*^$^!>5M*GOB*wt78Wa+O3=H$37CaDSU|222!0-+f5<(0N z+r=0d-h+Zvh=JjV7&OX+7#J>yLE0n-gculZib2v7sMGZb%2p6&V0aC6oP#g}!#AiS z66!&zUL4}O3}FTaUMRajn1N9h$}SXUV6=s@i-Z~2{KOd;K!ep4!VC=Y;tUKQLB14b zV8|4QG{+AJGcc4v*`OKjCUFLaPasE&FfjCsGcbGssTW~jm?6%<Q2!O=V^DSwXJ7!a zL4Dk9P_~081H(}$yFrwJ;i@<T!*`H+Q3i%5P;pRS?1MN1!%vU}p!o+028LfC3&a>0 z_$3$^Ktr+z#26UFBp4WegVcyKFepkeFo0$%9mE-!8T2J4ziZH|x0ZkmJAg_uHwgxY zeo!lpfq@}F0@Pt(V3@(cz!C*z&tYI-%z(1zGB7ZfLfP{e7#LeX4HO0jh6SJ)gPL)G zfq`MF1SDBGFfuUAlVD(&3UVVO1H&>2u-QTk2N)R`HbXcJ4onOTM<%ar6!$tW!N9N( z<ZNg+c@dQT2<lu=C*wPm4eDfoY+c5{zyRuG@JK=m4N(7CTyipBlTy8gBm)Cv6#_^h z0|RKZ0>m-}^;{VkI6xg#5TA*G0o(?5kYr%!1PL%OFnB@PpcYjGR6VEz43dVmP2wdX zSsNslA<4i1ncoHRz<BcdCRxU^$!D9ynVKcR?W8_QM0;q)WX@(~!v&I%$N_0shr~W0 z3C@48wmicmkOBq<hSQT{o3&Y=FfuS)oZQ<i9{E6$fnhpS4oWfIVPs%<A_-~QgIZf} zB^elILM1^IGXn#t70vKjk^wYU4-#VdBgw!p8_Z&0V3T5Cm@|1{lkjAL78@o3smXpV zVs5jAz_k`s3AmHO3Tj_VOF@c8kc6rfqW54Vg-8`3IR*v>rk9M9?b5|2A7~LUw2?yi z+f|BzVKG!qh!m>7mq5i&PiAb@PfUf#g2l?DASDrq(}ctZ@j*TWRm>BS#OENf*CMe& z>Oqcs#mK<0XY#~Wal=zmkfI4Ba{+22C>dOnVqn+`N|6i<3^zf89t;c|pn>}*lW(>v z8@-icV1P`EGcbGxwbh{&KWJEFJ;*2q1_n;h5D5bV2WUE7QhKspn-Y_<^yHv6B|dd& zNYMyVs3$$SsZGz&9IAL50|SGnG$dF+9nDB-g!4dMTTo99)U%75{IE@&H(MG~ZGm!j z<Yd-%WlvD&br;B7C<di=P_jVjutGbpAae?!c44TQT-YvNUn>nQZy6wC0-$OR6gVK4 zfR-MCOaOJnL2Qs4V3xi?YS4kwO@}lC!#=2F9}*iX#PkfR9uzg85@m)ocwniX1vD73 zL>f}0fE2HmhNL8r#T%h)kOojNfod~Q5wu+zQZ_U&GBE6uhNK%%SLTp3wC-nQU^oHu z7&8L{sC^4+aw#w~Fr0&`2ibc?x*noAfti5;)H68)D%Y497;Z^3Fq{RI)yxbGkEIzH zKr2TYSQ!|eOEWNB0;yqVV0b6Zz;GGF=3rp>EX}}h1(cLH85n*@Ln@dCZpe@ts2$M3 z4H*svu_tgdFob}LO9lpp84=tJ4D2$H8f*bK0|UPdB;9P_W?&GLVPLopas)R6gS-p_ z!!1zo@GvlF$Us5}G;n7v1F0k$Bp4X%Wf&OlgVabeFgQ<+?G%>;rPaeA5e5bZA5cS| zfq~-)0|P_U<latk$s`#D22e@{MK?$htQgFhyth-Cw-D+okWA&|x1GwWO)}uYOcu~^ zT`$ZH3=9mDWgtZcD0$4DY}(~qzeEO-yg><LoeU%agUs0gWrJ+oBm*AWWC3;W4#+St zoC7HU4Z%X$Ak)ssK+9J~28K&eHfTB4T_{_Dk%8eclx@HW2|ZA=i~*EL-pN3EO`zWJ zFDN^Lk%56t79tMn8S}`39m)VoNTA7d&=58#AxT225{~mwM}Z0;Q2x=7Mbs$TvJ4D! zpz?aM;Cc|uGm-^0OBonAK$+WF7QCv71(cdYWg%mzAXTYQHb}e_$_Dwk9m)o!_?b{P zXd&1pC>!Ll(@-|Z(NCakQ2qN?77{-SlfQOL*YnFkYy+7p0cC?sRg?pJ89X9oA%_^s zv5|wMLXdh#IdFx*0vZ+%mV-3RL9ULIgXS*=28K*INUVdpbcLW1VFm_{YYYqwWe|2f zBPhdjfL#RA%E0uRk%6H`4m_?64vwdc3=B8HQVa~oppg!8V4EDIEd%oEWI1U51dU?A z90+QIK-nFP3=B)4Y|yyIS}1!4qYneaR;XrBgzkZ|LE&^5%6<SE{DArt6j#Wp@RA%P zqCug-CObK*S4r|3G~ht#094lAfx7+4<f*;pb}!|?Bl<0%q|JylQ20xZfdMqL0E%cf zdB^}Fh|Mn#2|kboa`Kb8`jnWI<R|O(S=F1!BL*HF<rx^BK<)9Dhcp2|nF=(l2pT>F zNri)k;Tae>KqYr9gbf>hWK5EWL?p<~Ir0n)FF+bV%RJ;EnG)oZ3Md;ivIHs{KuVY% zGBPmKLJZ>o4H5Q3*`RQm3T3|msbqjS3RF8QOEWOMg^JCAssUvvs1Vb=$&UTvws%44 z0wTl&N&<_JytP@Lf#EYm4n{IPLQ?;D^3?ud-?vC2pg7zGwd)T|4>Zv&RD^gQG%2=1 zk%0lcN|b?tVLg-$nl;!l*>r+(=wfB?v`Y(U{lH3PNb$hHz`(K=$_CBiY=yEx!M{@( zQZ9jl732rdm>4MH4?@L3CZC$Tc7nL%InW#kBO*dUxdIf>S0>+`pv-t@GUG(?dQjqr zHB&)p5X1(V2J#N5atGOnOO325B-w$=WKb;!8LdEdxvDAy11lrA9AeN@g}5AKzLhEi zXs(D2JbmIcdG18_`a8-D3>=8y1?6q<3>wIK(0m}sNgyYJ*r1dP;)9$BG7guTqiW!( zDRAJPQG-|y(svok1_j~`HE?#T2Tvv4fpEZchfmZXql^g*3@k69>=XtDmUmEg1_J}* zCn!6Ufr0TGl%2)E!1xQw&Sqd>{0C*{FfcGOsYA@nWnf@rgR=8LgS6`P5Q%&S21Y)0 zh)W9?7#LuY2=cKgRD1#h14EhyIHj?G=3#L8EKdXMGqA^sH5eGU86mSpHJ}({VBi4t zL4q_P=5T;24qOI-CTw8o4CWwEIy2FNYGz<yu+;*`C@6FpJfLh)>InwTs4+r{)p#ui z20li}q#Z~h8+2ecM~i{MmLD4TWm*gjpo$ixph1g)K@ck52{IJQo}k6RAPi;C(qdo` zncTQpc(TD1oBBmskSYdLD6G?hgd@nLolrI?#t&(MXGB{-YV@FOT+rgTi&~J9iIstY z@fMWL#=yY%1j=S-U|@U=WpgkvNPN|TWB`ykPLKo*3PlD6kfEU5z`?-4%%lwo7j6ay zCO#+|G)pE4W%DsGFv>&Op!ooGZHS{m4i(lxgfFPy2r?7o8EGAenV|3mMJ%Y62B}xj zv1ecqLkeKf)Gx?&$~p`T;?VHY(1D~1kU<7I3=E)YaS$8iXu-)FR|rquGnGdbIlMr! zpqvIW$y5j8Jdl{(<hN6m6)zbuFi0{oFkCYL7sotOP<ueFZCOSJhC`DLr|C1Enw&UI zy#9(IcrKX*)c$#B$iM(<M1f3tY6z*3K;z*rp={7_;#(*iG=%sa$_5P^{)V!_6W2x% zy$+lV3@lJ~11AFm2b6t)lYxN`!j=aYwZae%18CS#9Lfd_70Mb-7MreDKLG9mI|~#J zN{kGX4^J2Ll7%`8Hc|;{9)ltq=5&x+6{s2z8-!tMU|s@=X&OzIo1tW@YsA2yj))e} zum-qjHAXVR9Lfe&%OI_4j11sO9_PumGsJm4pt2wt-^mMS=m&zLU51f?A<zgC?U1#e zAbAERZBTMB0#C-XfSOgH@&i=ZfMh|FaUeFR*amfbKx~km-jfw)iq}6df@DF^AP{Jl z2P6wJ0W>NPVuPA9pt=Uc2BrG9Q1zgM1Zq%gWW&?FX!4N7RLd<+aaAm1=DFo4Dv zLE;Kb3=Dsvdck8xd|-R)84^ItxsAabh6W}E2GG0`NW%gqNE08#KETAlAP80S0Hg-W z2CXJhGiG4W1?50y1_nbY8$7oSRinVdz~ByLgGT3rpzH)t<^s)->w#R#!oUEUECuxh z4zMsV#6T4>ure^DLfHzCHPQ^AzJ~)V14ABE9Mn}TH-?lC3s@N#nkRS8a%b$Bd~uer z?MG-DU}Rum1tllY6s;jt3=}t@Ec*${XJlaD1vTrY88a|wF@h#w6=#dr!+3J?kc9}m zpydq=3_K<{bcLBiQimB1`2|pU3mo#dq4HJ`c`Hzyqd4n7RDlgd0jSl0A`cqT0IfEU zocwXNI48{c9+L&<Ab7o#4Uu>kCI`-uXA<z7Tr@|oesvfFg9js|)9lH}z_1Qv9s>i9 z7n*gTkOWP3gDe0ISFl5-^?7_485mq+z{7bhpt%pf7zPG^sNRSeNPoLQ8xpIa>9Gmg z3=HWpkOF#vHbXr_Q4D0B{D3wCLt_l2M*>=u(g|fN=rAx$gR&iT7#QY3*$Fxf3@f4R z1|0^5jZpRi9R`M-Q1$^G28KgW_5&RTh6_-;K#N^&gW2^A3=X;s49}s88gv;LK0(<F zbQu_aLD>g%85o#iA&z^X%fP@3WrG&Wh(Xy3dJGI2P_}~}1A{%3ouJ3S;1LVy3pVI6 zFa$!`panK5^-x6(`V0&?Q1$|S28I$S`+z<J15C{WeFlb3s5q!uIStBIFkoO<91H1S zIv6l8Y>Z`Kr~qX$0|tg|v5+WmFl1oZ3sn<f$iQ$0%C3(vWMH}j<wO}WFus7YqYW8Y z-$N}(Fl1o(6U)F*2{P1>fdRCR0W{e1z>tASBo1QnBSQv8RVe$hAp@fsl>NkzfzcDn zerm|T7!GAWGh|@OiDRe-&*Z!?WMC<QO1v>-V626*-x@M7c0$?j3>g?FK-upN85pNR z*&hrU7#2a<KMWa|Rzump3>g@=K-s?y85j>j*?$Zf7%xHDe+}yy7#~47{|p%zKSJ66 z4H+02<00`4TJXdNWh)plFi6Kk60Cy}1A``%-C)GPU<qX(Fk)bEfvN{BlJbGF6^t1e zLZEC1V+Mu<5F6B-N-$<%$O3Ud<6XuK3`Ow_3{{K_3=51I7^<M+2__5-ZBTZD2?N6< zD0_hk1H&RH`+x}p!^U_>d_OQ@VAvH8iJA{43=Bu0>>nl!3|FD*K`XZEA3!+@rVI?P zp=<|J28K`Z3=Fl53=9dT3=BV^;tFOA3~ULIP;oG0VBm+c6U-PGWT5N@GX@52D0_h! z1A`@$eZY)?!2`;EV8*}@3}M%U*NG)UI1CEr3=El2wu3nXLot+{V9vnM0A)9rGcdG5 z*`UI8Vge*O4wy4AEQGQ_YtA-7)i_u%FdT%k6D$}QE<xE177Prx5}-qr3oIBIo<JoI zSTHbrg0df2FfjauvOx>j*b*VWSFmJY5KLrXr~`F4EEyQ&U~Fp!2IE9XkJQ1Ifx!{V zZm?xw2u*|xHyp5KV90=qGt}ELFq9@TFtmXTvSVOqNn~JX2W2xm28PKnwmk#GVyK1& z2L^@>iQpap!vO~dhJ8>6J#b)PI16Qi7Rp_NvK1T|7@k1c4vq{AAE0^@92pq?CNeP8 zgT@~k92pq6lOR4j;K;xr31vTUWMEKCf==5wF)$cF*$Pe!3=T;UM>se!FnA<E5?X>2 z14A5?o#Dj5Sds)uj0H{%49!q88=M#z`l0LvP7L)7i;@@^KqE~DoER9^B{48`f<nTX zfnjG7149=h1H%Dl28P2>4WOld=b&r_7Y2swNem3#AoVT`3{R367}7u?=fc47F^Pep z2c*}9f#G)&xI5NT09wqM%)kH|u>>^*q>>pJQW@(R7!JrWFz6&RFl2%ZQe<GTPG(@p z0vV*pz~G$>X?h<}WMGI$hK$dFR$%5q*$&DK3=PT9#*_*JLnoBIK!t%}8kBuNg@Iui zl>I=3fnj?x14A~bhE!!>I9#91z>o{FSe1d{d@=(=KFDHK28KJy&<Rsj28LJ33=D-J z4QdPwzmpjlib3kt7#KKHAdR2~H3n93D7#gSfl(XEZc}4mw1cwS)fgB9q3jMd28JXk zyMBTi14BNPGeeDmp$5ucpvJ(^3uUiRV_=w@0_nbQP-9?Nm%_kM3JP8|28Qh^3=Cx; zN2@b1987_vA<&xBD^RwA1_Q&h6b6QJkfSvi7(S<f*UYlqU}j*5=Vzz~Z?px)$KMnN zhCq;^;tUKdsgPg?4Z`!MLK+JW5)2GdsSFH3ph8K4fk819(oZXpU|`Tmg*0G51NEk< zkU5tF5)2HmVWkHW3=FoZkkEP|!NA}OWq*(WEwX@een>DdghJV%<+`y@HiskwLslvz zwJS(6Fcd@Cpb5|#sN)hO85mkp85lxAAtA}YFg2BdAq?ahNd|_wsSFI^py-3lf`R<X z^qG-?VNogrc%p>^v=wIshyxlvVE_*#fRuw3eu1)Jz0-B6kZ1r&ZiKQy9b*t5)VTe| z$iT1#;y@PAIMU%%1_sc$JV^dTDg#3l$We?845w2e{nUEU3;}4u1T^*tQgjvSBT(<< zRw@HSBq-h(7#QxQLdpTqFwJv_1>lM7cd3x|Dxf~hr&LHe0BXaYf{o}gLZSf_ZJ<F9 zP~Qf$5Es;+$unlC2QRb+HSvF^LdtPa=LXbm0!=A_2H`=D0{QGKBLf3x8o05|0vhDw zPh((+hK3GE4QLhtBrcf7zz_o!mrY|}h=;Nj(-;_1plsDN$n=N-XzQ?18YFH(hS);c zAm4jH*`U5#SQ;dcgDgl&gCrzSNaRA<pvm$oC>u0*)edEYqF@SCFQ~`2Fb%Tu0~A_o z(ij+G>p?C8tr>(W0{Q+T)R&+R%)K-QhB%NK1_p+wX&@&;X5!zZK?Y7hjzjh_Xq*r< z#0d&H&{!gf4H}~VoW{Ta>MDYU=)Xhsf|rV^F{U#xBtk7<PiJ6Ag0gwjA=wUOrD*!( zbt}Yp;S)v-3=DTCUtFQgB&{>~+X|(6$#n3-dvLTMI|k$cPzZn=19BLM4eGxrK+Ohq zKVc37bw9PzA)yTFej24SfW}H#Kz$9@bi^dCe>x<Mfnq2z9bDejg9kG~bGe{(WuPc3 zOox;KpeQO&htvz8An$;(K?!tbIs-#GC~-qQ3`%3q85tNBLp=i;LfiyX51J^1vOysZ znl1&c#{rq2EgcO>KcM(MmkwcrECY=nWPl6@VNftKFfhGGVt+?s|3G5rAlO{*CKs*} zm;8wkVJbkdxqeMvxGKK>dO9RMf~>d?WrLE=Qz#o$JiLRlLAm@3G?YOh2%BdDdFlsL z9ONm+3`j8p@)JLl4Vs4s*}=-d&;l}3JOk`k&^`hN24x5bJQAyy0ge_>tjJqJ+3^ev zjE)(TSFKh`3d{h<ENC?hLsSMN(}T=SgenEOB?HO^MP>n%4RTj~1|;@D?&^iIS1>TJ z&V{nqGB7Z%$e66RM#*p^X!IJo+<Zp{149io;C4Y=3SPr<0%|nK`gM~V*C^MY%7Bcg zg97S4L?uX);XPC(DA0aF*&v59XF~i6awu;mq`A|;z`!U0Wj8V~Fe*XWO$-c-8c=pK z0|TQGl-<I>z-$F!*MpYeFgijwpd~mgK2UZK0|QHVCdBs>7!dumi3|+v$xv}n{>p`_ z2Zc}>lnsixhD>m%gC_?&G8q`a1rGxQLvJQzc^D{5%$A8~0MFKfN+D3q(E_T@Ktm%? z3qYmE0x0_gBLl;7DEk5<1H*bK`vxNe!}d&Y(f|*^fh+?pxCaH}<jIWdwEd1lWWn2# zu4jV885mxI<`*DL5Xl5;Sc4d#TzQ|7f#D}a4>;C1vLIm&lF!JPT(!=v9+q}MLZImm zP~`!NDxoY$`T|82NDj3B0GxJ_jKHTJRPBQDk}Q&XT__u5KFCZ41_nN+-_X<ra_@`D zzU!sceq@6sIY2X~j5(0N2Tdt}rnEr2k3h0KIg|U=i`9$gKpT4ukU|<XoCAsvxg5x* zGf=&$3T1=pP5m73@(%DsJjfVk=t!1z4g*6kXfDbaVxD~t14ADp1A}u8NEHLmM5rTK zz;!<ZLtg<{oiqanRD&&O+>e2Q0j6<w!DPD)N=)a9Cns%CtG^C8?SO9v^o*BhX#9_8 z{6A=XffBGY;QGNl1_mxr{RCxmf`*9Hq3Y&C?SaZozP~|GZV_mSFax;uW-x%NTMSia zUNV_)qneg8RCpOw7^<CVCDiwzU3H+XMLs2y+cqkJri~dwN+z${sKf?ZLljdo`PxP$ zJ<xuz6sSQP(G1#(WY9K728NuH$^SNriB^?Bc6Wg?Llac%mdSyer0YQ`r3)&u1I@5K zNQUiYWMG(70-m}7XO0yRJq(9Rz|9_pD<$A;#qg{IJon1*vjp4-VBm)wOTo7r&1_J1 zWdN@UU|`?^ZMPCHo&0T+k|}5-l{{3>Av8V5klX{>k);k*cXYDqW_eLirU#AVf+|OS zsLV;w)D&C>v>nY2Dsvh|26Qk?9#rNmiVSG+OfOXCJc<mc7~TMtxribo#=yXE6e@EW zBx4A38|Y|?J5ZUcP~Utm1qTCoyUkLl7~|x^E$Wh+p*&D72OVAnN-ZGvuE`s>=<^*% zlKoLS`O%gj)_<i84E&QVw}#h)29K9O6@X?bPccH8$e_SE18P|?Kz8SyV`N}RVE|7S zFn|&VXg4;<%a=f%00xMjE1>h17$DmRuQ4)!w|jy-!d3>3da%QnL+t`Z0ACrX=?b2m zV_*QSYXt4)1G!xiwC?~a{v5J06m<3lgB+5$Arc$3Z~>+lv_b&Jc1BVITGRs*_k)Yq zGcbh0ISdT(NNiC58>S%#NxTJ#-G{{12CWT%I(jye_$nm!UL^J<5W60#;TDJkWxqgT ze?(&cL1J^4gTe{CLzF=biLHvnHbY{2AhA=B*h~fGo13<8WQt5FE(yplDlue$GK?6C zi;_Vi!6k`BB`}U_UJ8t92xAyA6yz6`K$L-4AT=P`5G-!AIcC>%GmezJ;&_nY<li48 zxnUfInwrh>A6*5fcQY|c3MtgoC=`|Er0Uug6y=xXC+Fu(*JoxF<tQ%CEJ@B#(3oua zQEB=HCPt3w4Q!0u%qhhs(*;=>C8nz~GYU$<^+KI*sGw-8V4zS_!!TWtg;9hLVlY(F zX!-(XM%n2B%#3QP2wS0&h6=W}3YjUob}7XrU?(fo)J%6^VU$ESBaN9+Wg0Uh*K`9G zMwaR4nHgE9FJxwvK@l>XzJrNTY8opeA4ruZOpbGU0Slu6SdOh$AvLEsb^3oMMnjl> z@#%M27=@;DvNMWvL0#pVmoi!KrwG{V)A?8#br3#=#uIiQLnR?T23x;?m63OPHY+1P zQh-BM8BRB3V-!aAEL6g1dKN3A3e2g@tO%!aO<%yuC_jBU8>2WER56lMMW?@DWt0(z zM-C_jpt+M95;GtfBuCz3W#pP}#KvgE3=4fEbzo=8iQtSVB&9|mAIS+Cp~vZV4R*$L zjMH~<G4g<7fp7XX4#qSt1qB5KXmng=Wz+^o2Pnjoraxn2^xJO1$!I4JPs!U$H5kL0 z>lqm4zh(sY7(f{kwDcc@r&usBbXYPl{9y;TnHV%dYY9LKK+7yay<o^JJXk~;G!|q8 zE+N5uO;9`37{NDYWMEJ>ftC#n3=F2AQFSH;276FRTCd2!;0_Y7VqoxQWMC+;VPNoO zWMKH<&A>2;k%8ex5Cg*$Mh1o~$OIhN0&_+NhHXfEOOSdbzBMBQgQx|<0k(_`46z;v zz9VQ!9h48=1mw)f!0>GPMIA=rdXPugf^A`7aN=cPhyb-gA{arvU@(6IFKEaQ5?~;C z7#~#KfcR^885meg7{N=7K>Rzr3=9@EjNs)DAU;eUG>;A9gXCFj7{RSbCtiknhLu7L z4AKpZ;ORh+g403_44N&B;PE36|F;kW1Lq7z@Hhg9uPe;Jz%z%D0n{Z0@tr}NL>4eI zfLgpD{yBLD2Hq8n3@aER9#T+XU{Kw_$N*{rf#jin1#fR~0v%$OqQJl);laQFs>wkL zKzu<D28IVv13>HlSWOrhK!-7a<ku-MFo-%ZFzjH0SO8NG8b1KZpH*OBkP2X6xB;3A z2Q|W=HiD+K|0*yrNGdWgcr9RJcma|JwbDQWb_<voK7a(E3Y-@(F@ScTfi#pVGBB{t zVPcSAW?%sEq2@7wmOg{{ApNWhm>2?}@<%}GS1>W0fb#!>_-mLLG*}?|ZIl=oB$hBS zSg<fK)PoEF35YFWVgOB?gZSA>3=Etbm>42hAU=dy2%1a>$<I|{VDNsx#E=0s5X85C zz{F61#CLhX#Lxld{{)$LhlybYnt2;o80x`30vW*hfQjJ(RD-%Q0|Vz1CWZ%4ekzFn zf{Eb+ln;{!P0)iJ1e2e^3i079koq@F3@@O3Hx&j3&JRos7Hkmtc`6JH5?`1Y0@&&y z0$>+1Ff)MmnS<gG=Hm{ihW#oG48APP3=@#}jx5X!Gm!XhEX)im*ib`k1Cl%^3p2w5 zC_h4#fq|2Qnc+u0JH!F&K>|F?3_my^{9mdJ3=#s&;3FhJ4w6!1U|_9aV9?-%$Qyz9 z2Fwf|P(IAT0Z@L18Uuru2{S_k65q~*nIQp*?`*=%P+tHQfEiE$<%0}hHDP9$0OiZ7 zGcfR4Ff*)x@*O~Y8)k+bP(Dom0VqFFoq>VXftld~ln+z?0LrgbXJ8QWV6JEQ02P2K z_yOfZ6)*^JL3|8zfC7|19b|wDGlKz?50kfm@?r8GQ2s`B1_l`)W`+nZNEAUrw4Q+h zv_=V(h;D#fyo8xy22=ygM+=~QHVp;_-xbUZE0Fk(E0`HJAo1N+Ff)J_7lF)!=|6!a z&$@z{;RTcrc2NBuW`++?fo2T`2Hp+K3>@4LAA>_+2Qz~Jl)n@tzlNDX1Ij<C!N9<p z!^~g-<-;rl?Y9Iu;Hw4$gI57Fg9lU|#J4M8W(Yvy*E<(5GbBI-U<PDB`5+Cf1<VYf ztqvdq!7grLW&mw>0P!O=85npgm>E_;)q@?}z{~*J=>U?i0?C&!Gwc8zp8={@pcV-5 zKs-2ClcAo0^$#-xXeTI015}<t1FGP>CTMjv3xfd?-;IHV!2*fz&A`Io0p-K=2SE8C z{j3Zu3<Xd=*aJK)3>8qmv35NJgA5A`LjzoZfkBvsg`oq=kJ4sfkl|oqSODcWYBMmf zUSVd~0Oi9h+yUip)MjAtzroA^+Nlci5Qy)5gPGw3lDx+aW`-M3KBPMZ+8zfL0BK+a z%~J6~f(Y#5C(H~SP`;B61B3J(W(ENyzVIDp1_>xX2_*l3nL&XUlFDHYG=TD(bQl-} z&oD4}K>77sbQl;oFEB6!Kn0HIFffR{U|>jq8VFjzqN2jWPym&O8CZcPKLg6w*JWVf z)L>y)0aXt(ZwHhQ(|-V>zMcVQ!2^f@1I&OIPz`~)3=9%1j0``Ze3$_od=MYj=rS+} zaWFCnK>0It85m@F7#Tntfk7qbHeCh=VHrk-4QTQ^!2Eg!2ABfS4q=dnTe=JkiVBPj zC%_62@)w|dm<0;_5C_2YYe4xh`4vz;%)tks{QtTP4BRG+3@<?ZdR_(wFFghZPS8p% z0f>PhzJvuMg9Mac0Ft+1WB_dj1|_PkdJGIYIxGwx0+2NFMUR0&+kk~(29&R&&%mH* z!ou(X$_J^}(qUof5JXjfLl9d3!!&pZK@@;AfGh}r@<H;3CM*mQNPLh52~d8dJ_CcP z0}I0rD1W*>1A~DL3&Ra4|2&9q!NTwW$_JST(mw&T-5uFSGlU@yU^if35OHB)0Bzg_ z$tM~xFz|Y?Fx-I3gZMHYEDSH8{BDrE4+{f_2qXkyK`sF0UjVh<_b@U%H9)k=K_?4I z7=l*9)G&ctyAS~e2G$xT@X?zfeykw_gGd7tXhs-(6p@4>L>}C%Gh|?Z$%E#LK<cL% zGBEJ;FhNeAF=SwXsZTJ1jG2KQX2`(MY6NN034rVeX#^XzfC+qR6^IWuXbltSR4TB= zFb(UCA%k%sgZ3FSFq|`HU|<bl1UneS{|@3uFoOFZyFo)m3=9k)aZS*ILIH%jN)rYK zP6<YadeGo7NC8MdOo9=#h6Stv#Fvs_1Wl*F`9>0qU<bm~gXBRA@?d-e2}TCclmv_q zvH)}}8Hj(-gn>a-hmira_#VUuEf3PvV60~VO|XCjKt2Lt(4;1auVl)=z_SIi2MfeE zF=b$2UBbWsn&blU!Oe2e-cHblL1P96umuModmTXXU<>v@)?tJAAhSUjG?WeEgO(U^ zo~dVG0OdS{00X#Z0^)-cjSHk>0^-jxWnhqa09ncb;_oqKU=Vr&ndk=bLGpqRAdBEY ze2`@z44Q`o@xev!2L^CQ1;oE%%D})`Z^Fm`8rcR3fJ-_H25`>>#Q$pw3NlE?1jN?@ zEqL-_0FUOu_?$ir44}CW5Z}j)fq^%KfdMqFhs*~}euDTlW(*8c6_9O3ApSfv28Mc( z1_lNVCP*RyDG;t;U@(C451KJB2-Pq!SU~xp6;yHs3=9ECeC`4U@Zw&Ofgs<4a0XPK z#hihGvxR{HG|Q@B!N8CPn)crU=}Ce3l_m`J44iuy7%ng|FhB(u#P&eCPB6aI9tH+b z*9pcq+QR_uI>GoLc~DOY#y0?+b-|1<4`e<El)uJ;fkE^D1A_*Xf5D)hfq`)e6N3R% z;HU+pdW?Yb!HMn)149Lr4^DIs7#May`L`?}wIyiRJIDbbzQ_v(2GGuT5FZp8APlO} zL40tcegoMJ58{8QH(_AV{KCNS0%{;Q75`vh_yOgEG=nh<#7E#%%fiS2x;y}60E`b> z{|w@T5}||yBe<^z;;ULRFbK&oG8jPhgX9Gz7#RYfd~o>#vH;ZA18D%KQVm9M-wwnF zw-0m}87iO}oGlp`I2{-nCZO?WurM$rSu!wGSu!y2NiZ^ijzWR)g(MgmK<lkRd~miD zVPrS~QC|<%ASb~H?(2aRfDBNVU}Sg!Q2>@VmSAMyU`1G9FTuzlfW-Fz`54MSV#&ZD zwuFJf0ErJOH$Z(wkooT|85m5~Fff45-%GNrXJF8>Vqg&3z`&3J)sSn&z#y`RfdRC1 z3#0+W=ikG?&;gY{Z^gi%<HE==0f}$v!pH#Xe1g=2<fU8~8CF2$L7@x68=!n)YX$}p zA4UeyK`=@6mJAFa0UsYmh7U*zczqZden9!D)(i}ypk)+nkPzs%W?&GDVPxQd^0!+v zFbJhEG6*2?c~ck}B%pkldIc!|4oH0h1A_(|14BK?#ow(N801nI7!05aKzxZ525@&7 zBoA^u2uDEWVGb&Q@-=K27<h9S87iRsBpU_>&ISgC3U-Ktmx1^#3=9<<5I)E(5Wc{{ zP!CQtAPxxMfGT)p!@wX|!pQIejSt$F0&<YPEdzsK1tYlk3*uMUGBB8&VPF9DenI@r zwhRnH7Z?~oommk7lPv=S{~ZPf(Eb$=U(}9)f%gdm!wk-PNVWo54#EpKA$(su1_qN5 zMsV*IlncO((g;R|6HxiJb_@)PF^minToCn_?HCy36BxmLLy&ry{0}sFP}dG5|Idzr zLAHRAVMaYSngLKgOaZ9t1kwPqKs|wx;Q&+~#0Ob;0?LP}zX9dL<Ut)9kbYBp1_px^ zMsUXl#@9+=WT>~`g*X6Y0B->!g9DUb0Mbyx$j|`gZ?tD%kgs86Sb)S=t6>DU^Fao} z<WE55@7gmks5CG#TtMQ>H83*Vfb!WK7#MV080#58?S7B}AOZCjNIM_Iw{l=$FaRyl z<bya6#MkOzWRQUJOB@&&jCvRuK!^W;)NgWNV9=Vt$Y6jZuhYZG@Bqq(Iq(CN|H6TR zL1aojBZCA#!~#c01_s_4j0~W5JjlREM+OGL1&j;^P<aqvZUG~M1(ZJ>B)@}^ApngZ z0p;%m$?sug03E{zGVhxs1B3htMg~y70K|86Vqg%gKf}nd1F9hvByfR|;Rlqz)ro<D z_X8sX=yV{EhVM=c42pjk88ieS4wiIgV31~E0v{NJEN=mow{T`)Q0HI*_ZyJq3!w5@ z&I}CoQUXj26;J_~1r1Psmoo!{qzDs32b2$!UjXHU94PUDkzoUr50eL-nFq3Pg);+# zk^~dO52!qdFCoFiARq|wz*f*oT#x~vV~ao<E;=(XsLC)gXh0RfG=PpW0?ETH2!P6i zR_3ZJFfo8m&qJ2afXc)4D+oa>1Z8m$wt(`DUFsPaL~NKCKs_0d0pK*?z{HRNRRE6T z2quOGG=2w^-|oV|AQ;2MumQ?H<ifxpm%#+?34zQ5@ntfY7(mA$f%s2d7#I`^m>6C_ z)jQO?f=W6jh7VAIXjcXX(F!I84q=FkVSE87zY!!~!^8kOGYMqiO;-j6-aCv80Z@5< zHwFf&9wr9Rx>b<8jvE7m`~)V32eJ_JLfjY_c&9Ld4}1m5*Vnr-Fes`pF@Vk!02Pg^ z+!z=*a~K#T<RNACI}pEsfk8q6!UqK(2p6F7E1-NMcLoNj4n~FvP=1*^1A|}>Bf|_R zf4VyZgXRQAh7}NgJp)KUeF7uH28aNduQY*?;Q$gJq~QdVe;j1s6h?*zP(G6f1B1*0 zMurzqzM2OEgXA1W@X@uPzM~Fk-De341BW7{Z<*!Ez`$9<!k_@=gO0oMWMELJVPP-; z3otN%6e!oQFnA#GK^h{U{8^q147?pI3>ip#sSXx~0!0RfJ)R5<S3MaRSQD5TCP4Y1 z(RAJiObi>4_@Ke=6Ci%QCj$ec7bu@IF*qne3;^>*m>D)GL-?TJ2H^u}{1Z^Vrxyc* z%?bvF7f}9cFVOHk1H%U>AEXzAe?a-Wy%-pT_b@O7s4y_pgIo*};N8Q(ke~vw@U0gE zgYp#yh72UW@D&Dz0wliK6$XY5DBs4Lfr0l11H%O<Kg*keLFNqu!v`e3-WvvnA4q)j zHw+9CstonuAOmUec*DS;pbBvSh#&Zdfx!WZAOD7d!2`-a?aja-{egiY1Ih=f7k$IP zPypqB^JZW${=&d80f}$(g@IuP65sU;1H%s0dWeM}4RK!>7!E)cg!wQq$p2tqcmU;t z<R!l_FnoaWC-^WhNQ2JHQG@6Q@kQS-GH^ioyL}iK^gl2%2q5t#KQJ;#K>6Rm<})&A z)I$X%d>I(zd6*askob~3ObixKzPm32gRuY;g98#@R)C4Y1IlmnWnfU2U}8vs^4It> zFqnuiGJuBhK~W6i+lnwUfL7td_%b4l4E3PZ_aK4aAPYdvZm0nuz71#(vpU3wpacZM z98i9&9|MDo4I_gF5?{}Tk--3oZ*IfL5P-z@uwi6~K;j45FxE3vAPL0VFfuei`TP7B z7^EE-85ThKAPYrp7#UVT`7iw#7>r#Q8BQSaZCn@`E+Fw;T^JcYAo1f|7#V&*`JVm^ z4DueJ`d<U$Ly&=zE{qHYP=2#N1A|ElBZCDJ-!_GjApwamlfuYQ0OeouXJ9bSU}QLe z#J9;{WViw4gF+94UqJaL0SpW>^*xLX9GVaZfCRLA7#ReR_$ED!3<gMiryfQI3nadG z4<kba5<jemks$%f?+IXFke<NE&;aFw%opupWaxnMw*)XS)Ei7;WLSYDU^#`6VFMCB zcnTxK2PA&X6h;OPEr^4K0vQ<OXD~8YAn{FSFfs%{`57R2&{QoF-*gTmLkE=40N#lJ zIx`6>un(lcg^6JWl>Y+6_hDezfW&9@VPMz+<?{qFFz^O2FkC?6-+=Pff*2S?eV7;? zAn^r#m>6C_`9VST3=I09;S6nvkAi|27|a5g7zChvumegM7$lJRtR)N#3Q+z`kOM#? zCP;ko3I+xbBtCBi1495BKLN_$Ss%o}pkKhmPyrJFIiP@vp##c?IRLbQ6_iaue2@cX zK;>Z$Sb@X`IRLb;6{H>}e*#G!<e(c+KD__`04f05D=j>Oi2-zk0muLlpLYfmgM|(x zgbaci7&PWEF@QG3g5*Jb!8uF}9#Hv|U<L;9B}@zvP<~x71A{;hGeZUvpR<RVp#Z|K zXMk0Y6CeU$KB#(J0p(8#W?<m`!Nj1T3vmFLFT>0*Ll43SWhoF|fyUne<-=;n6Hq>^ zcDw-Q!~M^|a04vBzyPWZLDi#yKEwhLA5=RAK>4uRF#?GXsvQ%M_@LUc0?LQgj-XAo zpb!I9R-oDuw6S&%sQw2DfU3tAPz@kHsCwiufH(le2i1-ONPJN3Xn@2A)s7ZWKCE_( zfbv25LA7H7ln<)RK(%9o0kr-H34p4{4kQJxUl<rxAn`%9;|3@nRy%@5NI^aV=?B%0 z51{g(+7MJben8@bYR4Z?KCE_RFof3sAOTSI$YBWaF|2w74WEN7fYpu)P<ap^R6A-w z`LNp20ErK(9W9`ISnUYfgA6k7PA~(5;SNTI2+;UHOu%XfBSQsL14x0)4n~F!C|@;% zfx&POBf|kCzSSN^h6_-BGf4gbBlvI(ka-}!)d5BZ(9T^DA5{H<s$&f!hzCJ@P<8A9 zx<n4908}4GKox+hU(l%63M4+LItFd?1*r$6co04Tl?T<1pz8Pq5+76@e?a1cs$&6T zhyy_CLDg}+1d>3Y4I_gE5+76@gZ2!AEQD3Zpl!n-KF9!2b({fJ52`&u)o}+BA5<Mr zK;na{;|)msI2Xoxh8<7=NPW!6a0AK*83?M5KS24g>i7o|A5<MHm_U34k_T1C22eh% zItJ}q200kS2UW*2pz@&51J^$*paP)kQKpBH;RF&NR2^SH;)AMV&<G~TK#+P+bqw0v z4C8~UV+m7;gFy12>KL@g86*#@jzRmJL41(BD5(DTfNB8M$Drys1Bnl+jw_J(pz3%5 z5+76@uYmGl)$s)+KBzi=0OiA~V-7Qj13~<HP<<=`6@UZ@1A_*X537zXpnOo}Bk#k& z0NRBO@&Skss*XLN^04X{v@;td594P*<zdxv0fJx80IH8GpaP)k7gQZjK;na{W6+jv zkbxiz<x3bCRzT%Jd{Aw;0m_HfcA#zFAoU<Vs5ZQTCJ&m(fXLT_RxmIye1Iz039XJf z%ppMp;+qvPF-So9pmG6JaDcXqgA4%iLFEQ$+c=C5DmMb4>S5(Z1ri@rZgfET&GpcN zV*^Yegn<E6aGZehK|Tce_yQ6i<l`GqKFEil`uqhFALL`uJRZnFFnJCOh=*W&3D6dE z1qO!than6Mf*h<222cU^PzDAC9##eqC_gxqfk9A!l_3Jk2M<z-urh%5u7kSQ6(D&T zR)!T&`OTpW3=$fw3_FncN*b&TH=quHr7_SR_dTAV^$)=e44?*wg(bv=um*<%ln-iP zfEpYgNPJL(Bft{UpZ^}pz@Xj30$#ldauA4b(8I!T04nbp#=yY4goWV-l%F2Pz#zJY zh2aC3U(dkM2@=@D0=^;!WB|;C999quz#(#ng+T$z2ZzW576t<-9~>f2SQr|hd~k@o zVPTj7<%4QTMh{ko1yKGDkb_JZ7*>Gzp!I(s0Zz~YLy&+10|SUJXu`m70EsVQ!oY9> zi7#Tpz;FSH57K`F%D)x{8q{K7c!0zguwh_$fy9@vVPN=S1)cu~X^;n9L1+!}F^Dg1 z!@$6S#0ME50OkJ%S>VCIAc4de@L*t2K;nZ|R2m@h<vkb}ERgup9t;c)*3k8TAOk@L z1V9z2gflRRgfK8fAn^r47#I@J_ythD9Y}o)149K8Um%8op#hCQ0m_d6sZU{Gm|+cF z{|6EfNMT@DfTRG#-vH$ofi&bWFzi6$3*;~`96;k=fbu7R)R!<Y+(6=kHX=Ph<A11! z3akfds9|9Efy5W6VF2G#1WJ@3c@Q5I4IutGkopz|22ec0_yR2q3<@@oC<Mua_y$n^ zTafx51_lo#zCaHHLwx{L0G8@ApnPzuodH>&3|f#N2b$>5VPxn4r4vI2hWrT7z$GKY z1Sr2Nf`Ngnhmm0g5}&h&kzoUr51u)l!N{-zw7tiWfni|;1B37aQ2mc8zyLa^0%Rdb z0ciOB0aPBmtab$>g8=9*GD8N23lR(q+*=qKG|>1CP(FCotOEl>2b2#}KLN`B9KpaK z;!)4QZ~;Ytf#Cs^57Y1h%2$YFV36`*VEBQ?2j3WF$iNU8$-v+g!oVN^+UAAiKnW-x zB+nYcz>opugO};nM=&s)fC_-u>BcZHXn^(&8Zt0|mgPz$Ffdpk@x>At7z&_#m;)=I z{4J3T416aT85W@NH$eF?^*f;aH<1hs^`QCu6G#Fe{tYM}rU7)!2PjIwK~}=R@B=Cj z<AaX=0Lkk{fmX*bFbIIQdKoe>I7cxsIQK9xfQ|zJ$^Qhc1MXm8038Ve;=}v@9!MHE zdl(oppnUK;-w6y16;M8So$nL|h7KqnCVvCUhskSzF6%O6U;wWJp25IS0p)|&0ncGz zIN=1zC3B-dSG5!{GQ5B)0K0Gt1A_qQmM=pFhI3I246ZvE7!;s<n7js*50dBH!N5=e z<%8Gtg657vw}TlnFo2i!9$;W7aD`Z?70tlF*TBfo0pr(4GcfQpFf!}_T_Xm%>kOI? z4?y|V(F_a<FBljepz%LI`B3EyKcIYYl)PbJ5CC0{XUM<+<10Y<;B~`)7#J*|{Q3jY z3=B>zj0_%70hoaSP(DbWm4%TZ1Il**t^4I+WN3i$!D~K21B*~Tco{ASBf|nHAG{1# zfRSMZln>Lt0m83mfEjQABESGM-~^NpGvEP~4|CuPC?CAg7&K4`x&qLUfk8Tkfk8%w zkwF8>hp9J!@*T1m7`Q($GB|+wpp&?u0s&wFm~sY&2q+)CB7%X5Ap^<>uZUn_Vkm&} zVLBS1eDH!q2_}XPC_g)kfk9h_iD3qm4^zJY#IHAGfUJPjVPrS}5<p4=C!l=r<g)=I z!v!dRQ5FM(yagk}2Ppqk76XGUsOttg+Zl8&6;$2<$_Fjy(*i9xgz{nf89YJ#A43KP zm;o7}sS+rk*M^ay0?Pl9#lWEEz{v0e%2&w-6`hO>8lZa>4H+0f%kg-97#SRp_%c3> z3;|GnO*Uwlj*+1N$_KBIG+|=!@CLR2kbIl~y5P=`fdRZk5;W}w<%3p4a>g(*%s}Ex z#4s@&fbw@{Gca%_FfrVK@?k;z0?G$hW(7>(O*Wv~(jT-n8MNxj2U`Cx%3)v-)nQ@~ z@PXu05T8?riNOHMzYLlYvtVMdfb!qvFfg#%FfnX^@-=cntKFFx1biX-Q*s#?BwUyn zG?4gWE=&vtNPLjILp_oJNI?LU4;mHY^kHI1fbys0GBC)`VPwdF@(<=RFmNtlWGI00 z!46!*$j|`gKLI&t3nRk>C|@p*fq``gBf|<PA0}V_11bPh;Nb`HK?F#{9!7>4Q2r_q z{{SPy3n+hX6a#}$0VBf?DF06$0|WmNMg|6dh<^Ee1_s?Tj0^%$KG*|q7#Sp>e6R;T zFxE3zKn0@nL8sO-F*rc^U?2TqWblCUVe%0H5DONA)N?Q~L<B<ku%Z=olPV~VL3~ij zS^<@RozK9)&%?yf0Oj))Ffizf)H5-3Km}llW(Ab*S-`-+S;E9{AqZjtI1%+Qfp=(u zEC4%j1p~tas62S7_8JC;7f?QUgTV#{2998e{^bP>43eM)iAa3j`aKK`3Q&Q&1q=)_ z2N)PEkoZyu7#JLo_#k-?BtA$!0?HRCWMGgv!oW~~#Fsk4z)*q22gx@e@#{efCO`!o z3mF)cPB1WRK;rYBU|_fa<->gR0m{!R1l=eKI>r&=LlB>rfsuhD1j1heau5q6g8~v? ziiMFu1HrFnkYQnDFhB?}fD|}D`8PoZa4<3iK>0jH3=EPF7#I?e_`DAo7&4%Iry>Rh znI{Yk4M=>cCkzZ7NPLj|1USE*fdQmo0aTzAWWWmsh80jgEKNLs@|S_+9T*utAn|!Y zB_ovosEC0<)dh5e7$gKhd}$X(298h&U#OUYLDhqiK?2HmsxM|>kXB%1(0~aPGcfQf zFftfG`8CB13@R#&3>HXyX%$8W2Pl6jNM3`H!2`;NIXD8!2PfJTM(}n*=yG82a$eAY z1Zxf>1L!J6umE`BZ~-F&XrCdnLhu6P7R18gW9AGDtR0LDAIwn~B7+T_gQji)BY0mT z%skM710xI2vR)?ef@K8@hI$5&0P7Ye@P<WXh3Os)3_K^`3K>9r))Pz&OFR%3gACl@ z!N9<J2cZt^z$Z)$&(PF;1gZOhrjDVW8SE0!E=bS~w4j61K`klJDkV@*f{rBdWnf@f z3_T*+gAsD!>v1R_bl_zR0|Ube$a(ePO@$!!QQ!sQ4B&;UAU;3n9$f~=!c`C-v{nFQ zzC}G~j~?ipAE*M*-K~F-_#2?|Fb9Fwg@WW^eDIz=1_lNT&^ZU7gFINkH_9?hhVnsM z^pGtCEm8#Cm;DHIh&`zN4ca0H60idup#U<7je!Bgp9STEcEEuQfEftd0SDs4d~kw| zfq{jQfx!oK6ENs{Dt1)<11NtnR6YZAe+1~jBM849yyFdI04zvBYxqDG#DT69W?%sC zU<2`C7J@dUae~ehgN7JrLmG$=3lY$EEs%Pce$aL;5Fe%=wA+dcw9yv4A*r4LyuAt} z06J|C6epnVQy>j613=rSKzx`1pxsYAa03{?yPZIMn10aaC6IcUeghszl)&_ZHXrfA zJOG-10&O+|3BY^++DwFO0BAE2hz~OWv=>MeW&r3U2VMpS5Fe%=w2=j*{u=0VWl)p| zK^y?%gEk|;a#}s;DDi60<;tMzyBQc5K>RaMK4=p&=vHFT8h+5((|bUh2pAZ^YxqI@ z*HAv_)EE#SCJ)L*AU;eUlxslz>7cVEK)HpHfdRxnpa^RJF+f(ZLj^!F0M6hbK1>7X z@-Pq|W*}&_G>8wg5VZOk#D}Q|Ej9-6Vd_CkdqHU=(+XldXz4CUevb(#{23q%ML}^0 z%SNDOmmmf3I2C}q7;FM)EDvNL+(Ih`1`r>XYd}MBAU;eUG}H#-!=eB*k_O^WuZIQ+ zXs8S%pa8uP7&H<F;=?q6M!G<Jm<6DbED#@N0cfBK#E0nz4Mc(XJy7#LSVJ7R3d#qK zBZ1`WPeKI@Kx=dv85mwb`Jl5yL5T=fl6|m6O+*=X5I!tXu7L7kC7p#m0|Tg_f`woJ zln+a!Ga&qW2AF~$5CQN4QBW9zMnOOZz@o&#fdPDK<GM(YECWM_1H=Kaf(g{;2Nhhf zk`2`72k~JA8>r6@;=|2z1{GAGlNcc-5kmx6fPn#4Qayn3VI|uG7mx;o{0vu!17P|5 z0+bI65m1jA6vQwecYs#XA!S<*cLoMO(1BRipyP)?`54rhKq~t?(D*Z;e3*e3(D>la z2dD^#mi?fnJjlne5CJviL3~(<fSU64AOTpAfZFaLJ}i+b_(OaQ3ju=wRK5e04-2s! zXnasp8@Xr)HFQBC0*ms9V9@>#q@onma6~DJLl_u9e3*|x?L1I6g&6>9wt@IC`5z$+ z44{$}CJ$<Mf%q_aP^$`5Qo`gNLOEbX=j4N_YSVQx8FeJ}nLsBefKFwCBs9>e4ItLS z>4lk$;*!7FKpYkZ*!8y{9tb~~z7Ql`2tHte1-x+^Bn-pXreDlt6!-LlO3wft-2;<j zU|=wVnyLVnM@WDcGBPnRfhP|@qM(y}K=khEhFOf_lIy^y)w3`taDxO9_~i7&EJpGA zB+#Kf3@i*4(3@Fd3izSgK*bzP3`CoP&LCo70q-6K@nQH6BdADb0<WnAiGi*}1ktad z=7V-7g7`4J4r0#q?^%q3mY_Qe85yJ?d*~P#K*zL#)#*YMfj8}e1)xM6`2Ha&28Zd6 z*^KH+U%(;52H8>vRRW?w=No}Srod);S2m*><J;*Qvl;anbEiMdW)zov20ng>i2+n~ zfmFkA*L1-gMsZ2d`BNaxpi?(MQZK-kFfiPk?wG?U&ScFxJt~K>tR8gc7DyRr0~1JD z0^}krh7_pjplw4SaTo?|Y5|25Xnzq*3`9Q$hZ7TcGd+k8!=T;xVD;emfQd3N=z*QX zR1e<ZfDmS2u!kDdftE~GLNtK)s35DK0yY@3+!tAVGt>hDP!GZ6)S%{k0JmSEl_N;9 z8EOz{Z90e#!^^;t$OPUd022ezGEfUZ*Xx4#Fbq0{3X~W?*M@?`Ku2wXXgR3G7Q!GN z6oc%Sg8CS=#vCdPrlvqG1}z;23qT1GsKuZa*-#-c^%iuyJcASi?3zW;NnRicP}2Yu z1)v4gAU+Jcae&)GQs6VOK!VVU8hqpfNW+8aFY_3~>%T(n3xGC9K}tcm9O}Lq&?W~+ z41_^@Xh7OQi+w?S7&ZjQC=-JKXpbCB5OnYiG~hvtfsuq6m>~AngBMaEOWXk;zr_Sz z%!@333+f=yqFrQhc4z>D?*2g*_k>u$umRc;fXOX@#uR8NENJ`?CeE-F>e35n8X}<< zfEM?{6@#idsDnU@c9F$hp&<cU%8D$m3w6*7XnhTq10@j^s04#LSO`w^LtP45vI-Yu zU|{HmIux`N6<J&f>QK-MQ)KZOQ1dlFXWk%5NO6Gu&%^*aZ5l}&ymJf`$Doy;$l{>m zO+ezH6`;uCphG=C;-H0{$l~nK5CSdOL>3Q%Iw%0NehOJ)Khy`H1(wL-jZlL?>n4%K z<)J|hT5pLg&I1((Eeb>y{|*f~(DFryI4JxX7#ND6K@D0L36X%1+)$T-)>A@6AmkTl zA_Xl&gor@MZBP$@mN!B~Afz|cV$iZkhzNvi1)ZM)3c3IthyaZ2g8CSArV~sIL_0wZ z0<9(l@nLu|%wo_e08Eg9fgulSj)OjuAOizK4b)@xpjCm$Qkl?@0ImK*7Pp25Dd;u> zWbs*0i$T|KAdA0-h7f2?9kO^T)Ip%tgrNRAT&@`EBG4*9xFBdm0O}yn>OW-h$54Yn zOVp6XCqf-`1GF<7N#YFD9MB3hgm66rgCaCYL2Ka<5)2HLP#;S`dy_CZJE%dRrE4%T z5G@Wh2ecv$#E0Q9s5zjOW-u`jZ3gmiJp&WN3u6!$fe(Wu7?>CypoxEm`V6!J456BV z!4xVES_p<Lz6}~epaovY;wz!%gVt?9(?3M|FH{1wS_mQnA+@0vfYw<-L?EOx)B@1@ zDToM!oC6gHt-FGVK*%^~2!YnlKt!PZ=SrvqXc-e!0!)cOgBr9x3M>F6TA|{gbyZLy zFvSHG2QAhC3qT10s0To+j-Wzd>MbkS|4a;^^-N$9D6s~r0dzeER0vGngo=ZfH-QD9 zgaFjXGtg?kK4^%7Ru@5)f~jh#Lr;KDk_QVx2vKNanSfU9GC(!Fu!N|Cks;8K`++9@ z7n=Pl(9C%Ybr7h74>AMne-Og~Dgjzg0pi2(Q>ewD9zRSBMBjy4>;XC<6(j(~hoS00 z>oA}~U<$Nh8&uGNr?kK#V4|MkD%79{pebyy7=&no1~sUg3K4;j#!&SWK;xVcAuzcM zYB6|{4lDv8Y@t!}0W|ps5dxDScQZ27OEG|&bRZGX;i4d#4Qc^+G7cmF#hak*deEVy zAR%ZkmEj6Bs6q2AAaNKz3pEEcg9H-;(N$27EeJ#@{}>nopgsUi=ztW$@CRt`1$49? zNUQ@o_>~QfGSKt}NF0XGLd8LY^e{0HeH7{-(1Z?%55nO1cZa$NH0TZzgyFwX@c`Jp zu26|0m^kc&YN+@|s0To^4NxI4brBW?!C)?&$lzoEjXN`erz_y13=9l&pf2?Yoi0_u zXeT+18FW}X*jBJI1<1*#3@@e^RxpY)E}Pz2!Kg1O1XcyM3#<xsln01$diuo*MsZ0a z@G;GZ>m*>tDNbjsWE7YD$^^0l(X9pdAQ%`JwoW$$NrR4X5CV_2gN#J<0!yYRRx*kk zT0;#72R%5UK$L;%4nYPf23Q9c8g&f!rcbP76lZLkzOs^0UlMeew;%)PS~rL;&|%vk z)`ICDL3YQ2od#?1Bkb;)u2{t=E-3-E8|HIZhkwWPz$!*@PteiXAj3gtn}ZC6wF0-X zf(~t$Vt{!WMsqTQ#9_Gsaqdgj^o=0fSU5q_((s^w*%~|jVHKlz{XKSwG%WaF(lJnR znC&p}Yitnpu-Y0X?g15t6{s-ry<k^MgU@vV`35Gg4G|XtAMk=Kab|jFHKTI<ZqT?d zH1t6M1Uh8{bRr^1DToh}2OYBk<8NVL0H3OX%m<wz0po-2eTQ_HL8C1U42M9&z);74 z%mdwVE&(pg!SeMCAOX<!e3${-7#J8pd%2PMpsm?3{&vvZ0Y8WbHh=+ib=U+XKIqc) z3ut^;?-t~Mqo9#A=rj)_gE#{N$U@M*V33g@1t1GLrXQ?fl&(JpatmB7<Z^A$j$N2i zklmmSvM@f#FQEOb$b8WLR2cshDDa>iN|05jL4)Sd85<BEbf^6WXiJq5)CmCzfL8Fr z3;=nq02=im4In;fJu9-j2efK~$%9w&L9-sn^WgO<P(H}-44~B;NPO_>4=_I%;$!e~ z53m5_!T|7U4k#aFKm%ws29ys9Jn-rbC?6C;(AWpfCNON7E?dW_Uk}m-Iw=h1ZZIDy z(m;IBIa)Azkg=d+vtWFXv7kexV0@5z(4kT=K1e<25GfcRq#l;Tz_rGf>1XR0<r%k3 ze_O{mxjq0i8v?pTnt_1<l)z(<_@H~`Gm!Y8YqCp__@FYX0f~Q!fq|h1iGLZi4-Scc zg@J)#2@?M*D4sVU34m^9--E=z4oW0Q{2QQS<&gNGMEVAa4+;y=>J5<JL1j58N3-~Y zc#tv+lt^K9FG&6fsIe)7qyUuYOrU&F9S$l2K&v-EMu7OB!1Y0r2PLWqBt9rrry%h` zMM41*ACwDfkobo{m2C%-z*z<chABvVQ0y&0<F7&E??B@pLE~RQ<KIEz3xX{80u=xS z$+_*djf}!3^`Jc`AYX&TK-tLwIxz<02cYpm_v#_5FF=zA?O8#VpMWM0x_=KzzMf$N zngY<Jd`JoyKzmq_`JjvXkollJEy#S(C4I<z0qE!#%tN3(EeQE~1_lE(1)xnX2n7rb z0ci4|bBmDW3(({n(D)P3_@F&7aQ&cku>noN0W>~nQw&@KC}*I_e?a3in1NJ7asnty z1<?4gemp2dK$AEO251UEn`A&nfE0iX2tbnuZIVHj2W^T$=7X*@MCOC`#31uweK*h{ zzThGg*2#le2-*aLtl<Kh13;T#kmX^WN0@#FbC4`j2%zyndtg8+K!^B(9bkZ_0JJFv zq5x6@gEqw=^FjA3BJ&H-^n>nPM3$d`CJ(xY5iAdie^3yEHqn3upp^=&_X+b6XcG;x z`~x%tL2Fu&<w2WhkomB&S(tgC<tHHddYAyL3Wo7Pw?Kjv!1w{sDjCKH-3*B=5390a z@}S!yk>z3CV~{*(lywEfyn4{h(+nU1&@GZM4WMDt3lIfhc@X~v5?_shf#C-lUjW(- z23Y_aO$FUJ2{RAG2W`@U@j<KBL7Q?w^%B?ukU#>G0iadl1!#QOcpS(A(4y@bNb(^5 z79>8XwFx@S3uYmRe+5nc35XAhe~^J71z$h{&?*|lXMwhIVDchpd=)gl2^!x8jUR%> zPXTSBL3UvYnt~QI{uDI+5;Xo6H2x7Z{uMO-6Dv@?jO61lXbM<BJ#{2`5j4IE8s7ws z?}Ek;LF1=@HqoGj0GfgpH2xGc{t`6)7Bv15H2xJd{u9t98e|82K~um2+Jk}|0%&{{ zG`<NM-vx~yg2wkvK@%uJ<F}yk=OFPx6U}Ro`P0wtWo)i@0d0GMx*1fqg`n|M(D)^2 z{1!C+6g2)4H2xM;em%nxQ~`!7X#6K={4Z#H7SJ{sBoBz7@m0|HCMf)R1_l=t0S1N; zG=2&izXXlng2tbM#$STQ--65s6)8uM1sE6@uAuRspz*(;@mW9xB60|z@m0|HCP;j6 zlfnf_0GtNU_$g@o5;T4b8h;8Je+e3Y3xZz{uF;Pm1i<_&X#6K={4Z#H@V#%yApoip zkoYQSd=oeybS@_Y1A_}(0MdjALF1>O@j-{e!Ab&9h_#@}PeJ1^LE~?M@j>wqGT;bI z0NSLug2sP>#{YuGX8~1eNIn)p<Ex<YO`v>ulfnfm0II)04hlizr=amm(D*HA{3&Ss z{fvhg4>KNNJkEH6@g(CZ#*2)X7%wv(RbV{Gc%Jbp<7vh#jAs~cFkWChz<7-DEaN%G zYm8zNOBfeTZ{5de#-0MXC20CZO-9x2_x3SPX0EriWbkovGBl1igE0)@EK|6U37BOW zZw#gljS&n(xR9X{Skf}y5KJ4I!x*M8hB1_30HRCtN{drdrk^;(s2*Tx0d<50jA0IA z7{Xa*Fd<Vg!!q6kOdA>_7={ob%jv?08O^6V9A?xCGB<}BZ3bf)B3PziG0S)pFby&Z z#xR5kS;iZ~L?8^yc%$hH4l~M3zi^n*HrUYI3}!lvVQ2<tnZj8nV3uXPF_bof(uQE# zARa;+8pj(NPR}^PsNiX73N_aP#xR313{BxI6Bx@F%&?3%0@H@ZP=;l^;q;?N7$eQh zO`yh^ff<(ZCQ#ZKOoQSR#xR0042`D89%YoC-gJ~vLCw+_YJdfdVGd&$n!;En)3+XF zG~@<FJXpveeme6pMhz!Jb0es3Qy9Y#&N6`uL0AUy#$XYHcq1@vXc}*5G+j}PQ6dqN zVho{XS;80=FovNyjAaI67(!T<@g{H)2+K0w7%XA{r9okDJpI@)MrAIrIEZgJT|tXc z+{=&wVzB|#VsjY75Y94#37Nteh6t7kOw4$??r}zOdCPc1h=@6qVF0DUb{b4RnCi^B zfSG}TdGf*(VXohoLB$9ILo?^}UB?;i8AGT4I?iauIiUw4+%Vnp1f#rCJ2Rxf1<y!; zN>nIb0G-NE5CLhElWJy$taO7Gdr(yj3<CYrH=STqQ!>V3&Vfvb(hLTOIr=!vInY1d z=p>_>QV<SvG@xrI6QJh!;V|bx|MX2Db3k`KgFK4vuMVg=3Q%)&K=(c~Fu;e&A+BX$ zV3;u7=oF)x66iK`Z04*$GbbO1IRX==ZvvSk1HA|l-90Cu=4e3O1KQvS8VyGeXN3vV zjZQPFDS?g$#^#<6Xy$<KsK#cF!G!6XK<0o}OJXxe0&=e?11x+%%Q&%_<1k^m(HT&D z;qaFQnmK+r!Y5$D^i3dhKr4W;xhDc@4lI0rGGI@K2@|Fpon=&00^N9p&71}_bL?@r zr(nYLO=lU^6hZqjK<0qDmhd#ez`(EqY7Xo4pJy56l^Q|!p)x@3%S2YT0krWDG%*2* zRwXWIvIY&8VpGS$0Lr9tO4FdhiLP!3)VvcA^H`6A%mZihhFpkwyeFssI?E`hco;{< zXaL=t1-kxyy5)IBbFK+yAm1@CEODG(b)M0TYXay_GSF;<<MdtU8ReAxnHU(Deg1=P yx&<BF53vKZm<w8}SVJ7lw1Rnhd=8_iCW8fNiwwxe&?!fd@mryL4M4hK3jhIsbKs}| delta 42346 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�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 diff --git a/pkg/ebpf/bpf_s390_bpfeb.go b/pkg/ebpf/bpf_s390_bpfeb.go index fef364a8..92dd6c4a 100644 --- a/pkg/ebpf/bpf_s390_bpfeb.go +++ b/pkg/ebpf/bpf_s390_bpfeb.go @@ -53,10 +53,16 @@ type BpfFilterValueT struct { Protocol uint8 DstPortStart uint16 DstPortEnd uint16 + DstPort1 uint16 + DstPort2 uint16 SrcPortStart uint16 SrcPortEnd uint16 + SrcPort1 uint16 + SrcPort2 uint16 PortStart uint16 PortEnd uint16 + Port1 uint16 + Port2 uint16 IcmpType uint8 IcmpCode uint8 Direction BpfDirectionT diff --git a/pkg/ebpf/bpf_s390_bpfeb.o b/pkg/ebpf/bpf_s390_bpfeb.o index ee345e6374f88487fcd8de8fa1581d7887e7282d..f116bfe59de2bb9743a6dd122357597612d9cf86 100644 GIT binary patch delta 56657 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 aT*{2wK_dtZ3=AS58Wc=hq3U4vNdN%3Kd!(4 delta 51613 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 diff --git a/pkg/ebpf/bpf_x86_bpfel.go b/pkg/ebpf/bpf_x86_bpfel.go index 30f26cf9..cbef91b4 100644 --- a/pkg/ebpf/bpf_x86_bpfel.go +++ b/pkg/ebpf/bpf_x86_bpfel.go @@ -53,10 +53,16 @@ type BpfFilterValueT struct { Protocol uint8 DstPortStart uint16 DstPortEnd uint16 + DstPort1 uint16 + DstPort2 uint16 SrcPortStart uint16 SrcPortEnd uint16 + SrcPort1 uint16 + SrcPort2 uint16 PortStart uint16 PortEnd uint16 + Port1 uint16 + Port2 uint16 IcmpType uint8 IcmpCode uint8 Direction BpfDirectionT diff --git a/pkg/ebpf/bpf_x86_bpfel.o b/pkg/ebpf/bpf_x86_bpfel.o index 618488d29577f13039992d61774fc2e62a3845d0..22fe778e99d008fbfef53a36938223d58aeed0a3 100644 GIT binary patch delta 48257 zcmbQRlzqoV_6ZtHJMM4PvSMV4<eZ$w7{~a2^HIinCdR*$U0K2zr%ay9Vp>0+0R$>n z?D!9&3!98U6hk@_0|N&G14Ch>A(-zk1g01g69d2u2^KH~Co-KOOj#q4E(V6eR(-HQ zVY304PG^Rg=N}B_GGw|yXwgV!CI(Xm1_n_kMlc=g+zXZ|Y%&JZqD)N;f(#4{p-i0& zYzzzxm5VQc9V*J)4wl~!aW4Zq69a<?0|SGuPzzW*(`a%Pt30F8=2@)!nJwX(Kt?by zAZr4-S67G`tZ6&c*O`V8@2N6wp2RtWm9cTMHoqg|qRF}ZQ<>8KP5vV!vspnPh>1x8 z#Fpb`1#6aIWMJ4ed9F~c6Z1ci0EmA9#DHRu;UJ&3GBALB!piXPFGy-TBLf2?0|Uch z0T7RYftBI+-_0??>$n(~ZswNrXJ*o5o*biC#&nWt^A$xkCPx8~Vut--l7XR6NCB)3 z9$~`rV7@;zTndF1!F*5zfGj8!SDI|CVpg953Eo0cuq=ZpD-)Oj3z=BggJ6Ct3kw5C zn<$Gm*pV=KQ5IIHC-#8ViLx*=fC65WMUBCV0TIHXEIYu_S11B;Z=n#xo_d&j{hh%2 z8AO>Np;#yaiHbr|NED>ALKBWFR2?f9m{BMKRWAyOQgn5ptWbFoc8GdWP((8@K-JYV z_`?m9gD6Oar1ZiRNXVtLKrIddOEbtiK`j=78jNnSDpZ{-R9*<H#SH#nb@dDkv91@v zI#?N$z;vOAB$!47@kB7cFv$c=$EutL(=d5ZiU$R1p@<Y%T$H67Ocy4BQW*n7tjbX^ zpPiY30Tk#keXI;^3=H+)EC<Rk3=D;$&>$Cq205C~MOpa42332V0B5~IXh>B@L9!xx zh*f*t0IRE93X!i|0^$2ZLlPtpvY(-HDMUgyXam@S%0&<hbXC`Z`5>2reJI2U<`;@U zq5vK>Dqvv-P+|nJ3Wc~q6homX5159=H8jW>7(`)dM~D|}KSQA?A6A9%#3Kapd7&sM z55N--l7SHM!c=H!mjo^Cpyh~v5ZHJISrv%G3q^Rr0)?XWXcj{gqpT`4@rdBC7^*H- zwF_(zD}xxAhQ+NY3xrQ7B=*-s5;=n?E5rxYQIMc7OoI5NS_=|)g=jvi)`CP?<syhY zED9m1nt`D@3MLPsbyZ5i4y;@PF<;lI7|gGS#VyR`g(9F*o`IoI7*f-K$}3Qg^@mn0 zqRg<65e6GjC<;lu@HmEs3_OlSASGL&C?rJC)afw5<5)x-YM=y|MpMWj%KCG%v6^bV ztg|#&9+CPXKCHHaghXL7BuHTnhldQb#@i3cmGBA-7E-dokQgWwhBz2*o-owmkeaie z0hXO$Rj8~pBv-&Jk`0CxI8YA>Lp=mBfB~ToR2ncaz_Mkmvn|+Tu<~R(q%>dvnWoGD zs*gbGH>+vbFdE8$Rl>YjC;|x*SR56K$U@{<7{HZAp`hI4$(rGeizmO<G-sT%Sy@Y+ z$x#E8qY>4YFtqxDI<im*T77|R2DLv#pw$=5NFk-k-8ycBtFNnImk_SLAT>1Z>g&v) zuf8n6K7}Pq^uicc=+dD2dJeXjmB9u~V^&{FA>#1r>misA%kZ$|hN!+EEm1`EbsMZ6 zR8W8tAWR=C!z^g^#jFmlW(q~2C4vaFM8K%Nl)&mh)egwS!W3u`=LOBUsn9|j+R~_8 z0uhHb5McR4HyE698Eiv187A*hH>pQR_<$|Yb@c|*tPH$hT9gUmAR5)Lh!O$j5LjHp zd<rWWbc5D_JkEfqUsr+opr8f$sgSJtwH{l22(9OYVD%hYH3x3{Fd)iaO6pfo6^^@t zMY9-MI}l&Lwt+(kU;PTQA7@homRf08zt)2jnXXD9*rkXHHXqD~#VyPs)URJXA@voG z3KkK^1nXBTQ2ojy>kKikde)8qlh5eu)XN4#;;>K>B2kE1Au{++278pDawVi9mURZT z7Z@1e^`In<dJsb&C=W0�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 UPoPsVAS1Uzmy&}V1Do>z0C7)ClK=n! delta 43491 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 ZCW8m)7EjQMSENzD#h_6@s8-l8D**dW(Sra0 diff --git a/pkg/ebpf/flow_filter.go b/pkg/ebpf/flow_filter.go index 598aff59..b34a3dd6 100644 --- a/pkg/ebpf/flow_filter.go +++ b/pkg/ebpf/flow_filter.go @@ -101,29 +101,25 @@ func (f *Filter) getFilterValue(config *FilterConfig) (BpfFilterValueT, error) { switch config.FilterProtocol { case "TCP": val.Protocol = syscall.IPPROTO_TCP - val.DstPortStart, val.DstPortEnd = getDstPorts(config) - val.SrcPortStart, val.SrcPortEnd = getSrcPorts(config) - val.PortStart, val.PortEnd = getPorts(config) case "UDP": val.Protocol = syscall.IPPROTO_UDP - val.DstPortStart, val.DstPortEnd = getDstPorts(config) - val.SrcPortStart, val.SrcPortEnd = getSrcPorts(config) - val.PortStart, val.PortEnd = getPorts(config) case "SCTP": val.Protocol = syscall.IPPROTO_SCTP - val.DstPortStart, val.DstPortEnd = getDstPorts(config) - val.SrcPortStart, val.SrcPortEnd = getSrcPorts(config) - val.PortStart, val.PortEnd = getPorts(config) case "ICMP": val.Protocol = syscall.IPPROTO_ICMP - val.IcmpType = uint8(config.FilterIcmpType) - val.IcmpCode = uint8(config.FilterIcmpCode) case "ICMPv6": val.Protocol = syscall.IPPROTO_ICMPV6 - val.IcmpType = uint8(config.FilterIcmpType) - val.IcmpCode = uint8(config.FilterIcmpCode) } + val.DstPortStart, val.DstPortEnd = getDstPortsRange(config) + val.DstPort1, val.DstPort2 = getDstPorts(config) + val.SrcPortStart, val.SrcPortEnd = getSrcPortsRange(config) + val.SrcPort1, val.SrcPort2 = getSrcPorts(config) + val.PortStart, val.PortEnd = getPortsRange(config) + val.Port1, val.Port2 = getPorts(config) + val.IcmpType = uint8(config.FilterIcmpType) + val.IcmpCode = uint8(config.FilterIcmpCode) + if config.FilterPeerIP != "" { ip := net.ParseIP(config.FilterPeerIP) if ip.To4() != nil { @@ -135,43 +131,67 @@ func (f *Filter) getFilterValue(config *FilterConfig) (BpfFilterValueT, error) { return val, nil } -func getSrcPorts(config *FilterConfig) (uint16, uint16) { +func getSrcPortsRange(config *FilterConfig) (uint16, uint16) { if config.FilterSourcePort.Type == intstr.Int { return uint16(config.FilterSourcePort.IntVal), 0 } - start, end, err := getPortsFromString(config.FilterSourcePort.String()) + start, end, err := getPortsFromString(config.FilterSourcePort.String(), "-") if err != nil { return 0, 0 } return start, end } -func getDstPorts(config *FilterConfig) (uint16, uint16) { +func getSrcPorts(config *FilterConfig) (uint16, uint16) { + port1, port2, err := getPortsFromString(config.FilterSourcePort.String(), ",") + if err != nil { + return 0, 0 + } + return port1, port2 +} + +func getDstPortsRange(config *FilterConfig) (uint16, uint16) { if config.FilterDestinationPort.Type == intstr.Int { return uint16(config.FilterDestinationPort.IntVal), 0 } - start, end, err := getPortsFromString(config.FilterDestinationPort.String()) + start, end, err := getPortsFromString(config.FilterDestinationPort.String(), "-") if err != nil { return 0, 0 } return start, end } -func getPorts(config *FilterConfig) (uint16, uint16) { +func getDstPorts(config *FilterConfig) (uint16, uint16) { + port1, port2, err := getPortsFromString(config.FilterDestinationPort.String(), ",") + if err != nil { + return 0, 0 + } + return port1, port2 +} + +func getPortsRange(config *FilterConfig) (uint16, uint16) { if config.FilterDestinationPort.Type == intstr.Int { return uint16(config.FilterPort.IntVal), 0 } - start, end, err := getPortsFromString(config.FilterPort.String()) + start, end, err := getPortsFromString(config.FilterPort.String(), "-") if err != nil { return 0, 0 } return start, end } -func getPortsFromString(s string) (uint16, uint16, error) { - ps := strings.SplitN(s, "-", 2) +func getPorts(config *FilterConfig) (uint16, uint16) { + port1, port2, err := getPortsFromString(config.FilterPort.String(), ",") + if err != nil { + return 0, 0 + } + return port1, port2 +} + +func getPortsFromString(s, sep string) (uint16, uint16, error) { + ps := strings.SplitN(s, sep, 2) if len(ps) != 2 { - return 0, 0, fmt.Errorf("invalid ports range. Expected two integers separated by hyphen but found %s", s) + return 0, 0, fmt.Errorf("invalid ports range. Expected two integers separated by %s but found %s", sep, s) } startPort, err := strconv.ParseUint(ps[0], 10, 16) if err != nil { @@ -181,11 +201,11 @@ func getPortsFromString(s string) (uint16, uint16, error) { if err != nil { return 0, 0, fmt.Errorf("invalid end port number %w", err) } - if startPort > endPort { + if sep == "-" && startPort > endPort { return 0, 0, fmt.Errorf("invalid port range. Start port is greater than end port") } if startPort == endPort { - return 0, 0, fmt.Errorf("invalid port range. Start and end port are equal. Remove the hyphen and enter a single port") + return 0, 0, fmt.Errorf("invalid port range. Start and end port are equal. Remove the %s and enter a single port", sep) } if startPort == 0 { return 0, 0, fmt.Errorf("invalid start port 0") @@ -193,9 +213,12 @@ func getPortsFromString(s string) (uint16, uint16, error) { return uint16(startPort), uint16(endPort), nil } -func ConvertFilterPortsToInstr(intPort int32, rangePorts string) intstr.IntOrString { - if rangePorts == "" { - return intstr.FromInt32(intPort) +func ConvertFilterPortsToInstr(intPort int32, rangePorts, ports string) intstr.IntOrString { + if rangePorts != "" { + return intstr.FromString(rangePorts) + } + if ports != "" { + return intstr.FromString(ports) } - return intstr.FromString(rangePorts) + return intstr.FromInt32(intPort) } diff --git a/pkg/ebpf/flow_filter_test.go b/pkg/ebpf/flow_filter_test.go index a8f673d8..dd4561d2 100644 --- a/pkg/ebpf/flow_filter_test.go +++ b/pkg/ebpf/flow_filter_test.go @@ -13,31 +13,31 @@ import ( func TestGetPortsFromString(t *testing.T) { testCases := []struct { - input string + portsRange string expectedStart uint16 expectedEnd uint16 expectedError error }{ { - input: "80-90", + portsRange: "80-90", expectedStart: 80, expectedEnd: 90, expectedError: nil, }, { - input: "90-80", + portsRange: "90-80", expectedStart: 0, expectedEnd: 0, expectedError: fmt.Errorf("invalid port range. Start port is greater than end port"), }, { - input: "80", + portsRange: "80", expectedStart: 0, expectedEnd: 0, - expectedError: fmt.Errorf("invalid ports range. Expected two integers separated by hyphen but found 80"), + expectedError: fmt.Errorf("invalid ports range. Expected two integers separated by - but found 80"), }, { - input: "80000-8080", + portsRange: "80000-8080", expectedStart: 0, expectedEnd: 0, expectedError: fmt.Errorf("invalid start port number strconv.ParseUint: parsing \"80000\": value out of range"), @@ -45,7 +45,7 @@ func TestGetPortsFromString(t *testing.T) { } for _, tc := range testCases { - start, end, err := getPortsFromString(tc.input) + start, end, err := getPortsFromString(tc.portsRange, "-") if tc.expectedError != nil { require.Error(t, err) require.Equal(t, tc.expectedError.Error(), err.Error()) @@ -79,6 +79,7 @@ func TestFilter_getFlowFilterValue(t *testing.T) { FilterProtocol: "TCP", FilterSourcePort: intstr.FromInt32(8080), FilterDestinationPort: intstr.FromString("8000-9000"), + FilterPort: intstr.FromString("3000,4000"), } value, err := f.getFilterValue(config) @@ -90,40 +91,66 @@ func TestFilter_getFlowFilterValue(t *testing.T) { assert.Equal(t, uint16(0), value.SrcPortEnd) assert.Equal(t, uint16(8000), value.DstPortStart) assert.Equal(t, uint16(9000), value.DstPortEnd) + assert.Equal(t, uint16(3000), value.Port1) + assert.Equal(t, uint16(4000), value.Port2) } -func TestGetSrcPorts(t *testing.T) { +func TestGetSrcPortsRange(t *testing.T) { config := &FilterConfig{ FilterSourcePort: intstr.FromString("8000-9000"), } - start, end := getSrcPorts(config) + start, end := getSrcPortsRange(config) assert.Equal(t, uint16(8000), start) assert.Equal(t, uint16(9000), end) } -func TestGetDstPorts(t *testing.T) { +func TestGetSrcPorts(t *testing.T) { + config := &FilterConfig{ + FilterSourcePort: intstr.FromString("8000,9000"), + } + p1, p2 := getSrcPorts(config) + + assert.Equal(t, uint16(8000), p1) + assert.Equal(t, uint16(9000), p2) +} + +func TestGetDstPortsRange(t *testing.T) { config := &FilterConfig{ FilterDestinationPort: intstr.FromInt32(8080), } - start, end := getDstPorts(config) + start, end := getDstPortsRange(config) assert.Equal(t, uint16(8080), start) assert.Equal(t, uint16(0), end) } +func TestGetDstPorts(t *testing.T) { + config := &FilterConfig{ + FilterDestinationPort: intstr.FromString("8080,9000"), + } + p1, p2 := getDstPorts(config) + + assert.Equal(t, uint16(8080), p1) + assert.Equal(t, uint16(9000), p2) +} + func TestConvertFilterPortsToInstr(t *testing.T) { t.Run("converts int port", func(t *testing.T) { port := int32(80) - result := ConvertFilterPortsToInstr(port, "") + result := ConvertFilterPortsToInstr(port, "", "") require.Equal(t, intstr.FromInt32(port), result) }) t.Run("converts string range", func(t *testing.T) { rangeStr := "80-90" - result := ConvertFilterPortsToInstr(0, rangeStr) + result := ConvertFilterPortsToInstr(0, rangeStr, "") require.Equal(t, intstr.FromString(rangeStr), result) }) - + t.Run("converts string ports", func(t *testing.T) { + portsStr := "80,90" + result := ConvertFilterPortsToInstr(0, "", portsStr) + require.Equal(t, intstr.FromString(portsStr), result) + }) } diff --git a/pkg/ebpf/tracer.go b/pkg/ebpf/tracer.go index a2598c43..6eb301ed 100644 --- a/pkg/ebpf/tracer.go +++ b/pkg/ebpf/tracer.go @@ -39,6 +39,8 @@ const ( constTraceMessages = "trace_messages" constEnableRtt = "enable_rtt" constEnableDNSTracking = "enable_dns_tracking" + constDNSTrackingPort = "dns_port" + dnsDefaultPort = 53 constEnableFlowFiltering = "enable_flows_filtering" pktDropHook = "kfree_skb" constPcaEnable = "enable_pca" @@ -79,12 +81,14 @@ type FlowFetcherConfig struct { CacheMaxSize int PktDrops bool DNSTracker bool + DNSTrackerPort uint16 EnableRTT bool EnableFlowFilter bool EnablePCA bool FilterConfig *FilterConfig } +// nolint:cyclop func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) { if err := rlimit.RemoveMemlock(); err != nil { log.WithError(err). @@ -110,8 +114,12 @@ func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) { } enableDNSTracking := 0 + dnsTrackerPort := uint16(dnsDefaultPort) if cfg.DNSTracker { enableDNSTracking = 1 + if cfg.DNSTrackerPort != 0 { + dnsTrackerPort = cfg.DNSTrackerPort + } } if enableDNSTracking == 0 { @@ -128,6 +136,7 @@ func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) { constTraceMessages: uint8(traceMsgs), constEnableRtt: uint8(enableRtt), constEnableDNSTracking: uint8(enableDNSTracking), + constDNSTrackingPort: dnsTrackerPort, constEnableFlowFiltering: uint8(enableFlowFiltering), }); err != nil { return nil, fmt.Errorf("rewriting BPF constants definition: %w", err) diff --git a/pkg/pbflow/flow_grpc.pb.go b/pkg/pbflow/flow_grpc.pb.go index f9a4eb46..ac00dda6 100644 --- a/pkg/pbflow/flow_grpc.pb.go +++ b/pkg/pbflow/flow_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v3.19.4 // source: proto/flow.proto @@ -15,8 +15,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Collector_Send_FullMethodName = "/pbflow.Collector/Send" @@ -49,20 +49,24 @@ func (c *collectorClient) Send(ctx context.Context, in *Records, opts ...grpc.Ca // CollectorServer is the server API for Collector service. // All implementations must embed UnimplementedCollectorServer -// for forward compatibility +// for forward compatibility. type CollectorServer interface { Send(context.Context, *Records) (*CollectorReply, error) mustEmbedUnimplementedCollectorServer() } -// UnimplementedCollectorServer must be embedded to have forward compatible implementations. -type UnimplementedCollectorServer struct { -} +// UnimplementedCollectorServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedCollectorServer struct{} func (UnimplementedCollectorServer) Send(context.Context, *Records) (*CollectorReply, error) { return nil, status.Errorf(codes.Unimplemented, "method Send not implemented") } func (UnimplementedCollectorServer) mustEmbedUnimplementedCollectorServer() {} +func (UnimplementedCollectorServer) testEmbeddedByValue() {} // UnsafeCollectorServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to CollectorServer will @@ -72,6 +76,13 @@ type UnsafeCollectorServer interface { } func RegisterCollectorServer(s grpc.ServiceRegistrar, srv CollectorServer) { + // If the following call pancis, it indicates UnimplementedCollectorServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Collector_ServiceDesc, srv) } diff --git a/pkg/pbpacket/packet_grpc.pb.go b/pkg/pbpacket/packet_grpc.pb.go index 5aa9685d..fce16898 100644 --- a/pkg/pbpacket/packet_grpc.pb.go +++ b/pkg/pbpacket/packet_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v3.19.4 // source: proto/packet.proto @@ -15,8 +15,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Collector_Send_FullMethodName = "/pbpacket.Collector/Send" @@ -49,20 +49,24 @@ func (c *collectorClient) Send(ctx context.Context, in *Packet, opts ...grpc.Cal // CollectorServer is the server API for Collector service. // All implementations must embed UnimplementedCollectorServer -// for forward compatibility +// for forward compatibility. type CollectorServer interface { Send(context.Context, *Packet) (*CollectorReply, error) mustEmbedUnimplementedCollectorServer() } -// UnimplementedCollectorServer must be embedded to have forward compatible implementations. -type UnimplementedCollectorServer struct { -} +// UnimplementedCollectorServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedCollectorServer struct{} func (UnimplementedCollectorServer) Send(context.Context, *Packet) (*CollectorReply, error) { return nil, status.Errorf(codes.Unimplemented, "method Send not implemented") } func (UnimplementedCollectorServer) mustEmbedUnimplementedCollectorServer() {} +func (UnimplementedCollectorServer) testEmbeddedByValue() {} // UnsafeCollectorServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to CollectorServer will @@ -72,6 +76,13 @@ type UnsafeCollectorServer interface { } func RegisterCollectorServer(s grpc.ServiceRegistrar, srv CollectorServer) { + // If the following call pancis, it indicates UnimplementedCollectorServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Collector_ServiceDesc, srv) } diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md index 8bf0e5b7..33c88305 100644 --- a/vendor/github.com/cespare/xxhash/v2/README.md +++ b/vendor/github.com/cespare/xxhash/v2/README.md @@ -70,3 +70,5 @@ benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') - [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) - [FreeCache](https://github.com/coocood/freecache) - [FastCache](https://github.com/VictoriaMetrics/fastcache) +- [Ristretto](https://github.com/dgraph-io/ristretto) +- [Badger](https://github.com/dgraph-io/badger) diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go index a9e0d45c..78bddf1c 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash.go @@ -19,10 +19,13 @@ const ( // Store the primes in an array as well. // // The consts are used when possible in Go code to avoid MOVs but we need a -// contiguous array of the assembly code. +// contiguous array for the assembly code. var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} // Digest implements hash.Hash64. +// +// Note that a zero-valued Digest is not ready to receive writes. +// Call Reset or create a Digest using New before calling other methods. type Digest struct { v1 uint64 v2 uint64 @@ -33,19 +36,31 @@ type Digest struct { n int // how much of mem is used } -// New creates a new Digest that computes the 64-bit xxHash algorithm. +// New creates a new Digest with a zero seed. func New() *Digest { + return NewWithSeed(0) +} + +// NewWithSeed creates a new Digest with the given seed. +func NewWithSeed(seed uint64) *Digest { var d Digest - d.Reset() + d.ResetWithSeed(seed) return &d } // Reset clears the Digest's state so that it can be reused. +// It uses a seed value of zero. func (d *Digest) Reset() { - d.v1 = primes[0] + prime2 - d.v2 = prime2 - d.v3 = 0 - d.v4 = -primes[0] + d.ResetWithSeed(0) +} + +// ResetWithSeed clears the Digest's state so that it can be reused. +// It uses the given seed to initialize the state. +func (d *Digest) ResetWithSeed(seed uint64) { + d.v1 = seed + prime1 + prime2 + d.v2 = seed + prime2 + d.v3 = seed + d.v4 = seed - prime1 d.total = 0 d.n = 0 } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go index 9216e0a4..78f95f25 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go @@ -6,7 +6,7 @@ package xxhash -// Sum64 computes the 64-bit xxHash digest of b. +// Sum64 computes the 64-bit xxHash digest of b with a zero seed. // //go:noescape func Sum64(b []byte) uint64 diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go index 26df13bb..118e49e8 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go @@ -3,7 +3,7 @@ package xxhash -// Sum64 computes the 64-bit xxHash digest of b. +// Sum64 computes the 64-bit xxHash digest of b with a zero seed. func Sum64(b []byte) uint64 { // A simpler version would be // d := New() diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go index e86f1b5f..05f5e7df 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go @@ -5,7 +5,7 @@ package xxhash -// Sum64String computes the 64-bit xxHash digest of s. +// Sum64String computes the 64-bit xxHash digest of s with a zero seed. func Sum64String(s string) uint64 { return Sum64([]byte(s)) } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go index 1c1638fd..cf9d42ae 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go @@ -33,7 +33,7 @@ import ( // // See https://github.com/golang/go/issues/42739 for discussion. -// Sum64String computes the 64-bit xxHash digest of s. +// Sum64String computes the 64-bit xxHash digest of s with a zero seed. // It may be faster than Sum64([]byte(s)) by avoiding a copy. func Sum64String(s string) uint64 { b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})) diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 2466ae3d..3a7e5ab1 100644 --- a/vendor/golang.org/x/net/html/doc.go +++ b/vendor/golang.org/x/net/html/doc.go @@ -104,7 +104,7 @@ tokenization, and tokenization and tree construction stages of the WHATWG HTML parsing specification respectively. While the tokenizer parses and normalizes individual HTML tokens, only the parser constructs the DOM tree from the tokenized HTML, as described in the tree construction stage of the -specification, dynamically modifying or extending the docuemnt's DOM tree. +specification, dynamically modifying or extending the document's DOM tree. If your use case requires semantically well-formed HTML documents, as defined by the WHATWG specification, the parser should be used rather than the tokenizer. diff --git a/vendor/golang.org/x/net/http/httpguts/httplex.go b/vendor/golang.org/x/net/http/httpguts/httplex.go index 6e071e85..9b4de940 100644 --- a/vendor/golang.org/x/net/http/httpguts/httplex.go +++ b/vendor/golang.org/x/net/http/httpguts/httplex.go @@ -12,7 +12,7 @@ import ( "golang.org/x/net/idna" ) -var isTokenTable = [127]bool{ +var isTokenTable = [256]bool{ '!': true, '#': true, '$': true, @@ -93,12 +93,7 @@ var isTokenTable = [127]bool{ } func IsTokenRune(r rune) bool { - i := int(r) - return i < len(isTokenTable) && isTokenTable[i] -} - -func isNotToken(r rune) bool { - return !IsTokenRune(r) + return r < utf8.RuneSelf && isTokenTable[byte(r)] } // HeaderValuesContainsToken reports whether any string in values @@ -202,8 +197,8 @@ func ValidHeaderFieldName(v string) bool { if len(v) == 0 { return false } - for _, r := range v { - if !IsTokenRune(r) { + for i := 0; i < len(v); i++ { + if !isTokenTable[v[i]] { return false } } diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 43557ab7..105c3b27 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -490,6 +490,9 @@ func terminalReadFrameError(err error) bool { // returned error is ErrFrameTooLarge. Other errors may be of type // ConnectionError, StreamError, or anything else from the underlying // reader. +// +// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID +// indicates the stream responsible for the error. func (fr *Framer) ReadFrame() (Frame, error) { fr.errDetail = nil if fr.lastFrame != nil { @@ -1521,7 +1524,7 @@ func (fr *Framer) maxHeaderStringLen() int { // readMetaFrame returns 0 or more CONTINUATION frames from fr and // merge them into the provided hf and returns a MetaHeadersFrame // with the decoded hpack values. -func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { +func (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) { if fr.AllowIllegalReads { return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders") } @@ -1592,7 +1595,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { } // It would be nice to send a RST_STREAM before sending the GOAWAY, // but the structure of the server's frame writer makes this difficult. - return nil, ConnectionError(ErrCodeProtocol) + return mh, ConnectionError(ErrCodeProtocol) } // Also close the connection after any CONTINUATION frame following an @@ -1604,11 +1607,11 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { } // It would be nice to send a RST_STREAM before sending the GOAWAY, // but the structure of the server's frame writer makes this difficult. - return nil, ConnectionError(ErrCodeProtocol) + return mh, ConnectionError(ErrCodeProtocol) } if _, err := hdec.Write(frag); err != nil { - return nil, ConnectionError(ErrCodeCompression) + return mh, ConnectionError(ErrCodeCompression) } if hc.HeadersEnded() { @@ -1625,7 +1628,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { mh.HeadersFrame.invalidate() if err := hdec.Close(); err != nil { - return nil, ConnectionError(ErrCodeCompression) + return mh, ConnectionError(ErrCodeCompression) } if invalid != nil { fr.errDetail = invalid diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index ce2e8b40..c5d08108 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -732,11 +732,7 @@ func isClosedConnError(err error) bool { return false } - // TODO: remove this string search and be more like the Windows - // case below. That might involve modifying the standard library - // to return better error types. - str := err.Error() - if strings.Contains(str, "use of closed network connection") { + if errors.Is(err, net.ErrClosed) { return true } @@ -1482,6 +1478,11 @@ func (sc *serverConn) processFrameFromReader(res readFrameResult) bool { sc.goAway(ErrCodeFlowControl) return true case ConnectionError: + if res.f != nil { + if id := res.f.Header().StreamID; id > sc.maxClientStreamID { + sc.maxClientStreamID = id + } + } sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev) sc.goAway(ErrCode(ev)) return true // goAway will handle shutdown diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index ce375c8c..2fa49490 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -936,7 +936,20 @@ func (cc *ClientConn) setGoAway(f *GoAwayFrame) { } last := f.LastStreamID for streamID, cs := range cc.streams { - if streamID > last { + if streamID <= last { + // The server's GOAWAY indicates that it received this stream. + // It will either finish processing it, or close the connection + // without doing so. Either way, leave the stream alone for now. + continue + } + if streamID == 1 && cc.goAway.ErrCode != ErrCodeNo { + // Don't retry the first stream on a connection if we get a non-NO error. + // If the server is sending an error on a new connection, + // retrying the request on a new one probably isn't going to work. + cs.abortStreamLocked(fmt.Errorf("http2: Transport received GOAWAY from server ErrCode:%v", cc.goAway.ErrCode)) + } else { + // Aborting the stream with errClentConnGotGoAway indicates that + // the request should be retried on a new connection. cs.abortStreamLocked(errClientConnGotGoAway) } } diff --git a/vendor/golang.org/x/oauth2/internal/client_appengine.go b/vendor/golang.org/x/oauth2/internal/client_appengine.go deleted file mode 100644 index d28140f7..00000000 --- a/vendor/golang.org/x/oauth2/internal/client_appengine.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build appengine - -package internal - -import "google.golang.org/appengine/urlfetch" - -func init() { - appengineClientHook = urlfetch.Client -} diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go index 572074a6..b9db01dd 100644 --- a/vendor/golang.org/x/oauth2/internal/transport.go +++ b/vendor/golang.org/x/oauth2/internal/transport.go @@ -18,16 +18,11 @@ var HTTPClient ContextKey // because nobody else can create a ContextKey, being unexported. type ContextKey struct{} -var appengineClientHook func(context.Context) *http.Client - func ContextClient(ctx context.Context) *http.Client { if ctx != nil { if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok { return hc } } - if appengineClientHook != nil { - return appengineClientHook(ctx) - } return http.DefaultClient } diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go index 90a2c3d6..09f6a49b 100644 --- a/vendor/golang.org/x/oauth2/oauth2.go +++ b/vendor/golang.org/x/oauth2/oauth2.go @@ -393,7 +393,7 @@ func ReuseTokenSource(t *Token, src TokenSource) TokenSource { } } -// ReuseTokenSource returns a TokenSource that acts in the same manner as the +// ReuseTokenSourceWithExpiry returns a TokenSource that acts in the same manner as the // TokenSource returned by ReuseTokenSource, except the expiry buffer is // configurable. The expiration time of a token is calculated as // t.Expiry.Add(-earlyExpiry). diff --git a/vendor/google.golang.org/appengine/LICENSE b/vendor/google.golang.org/appengine/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/google.golang.org/appengine/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go deleted file mode 100644 index 0569f5dd..00000000 --- a/vendor/google.golang.org/appengine/internal/api.go +++ /dev/null @@ -1,653 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build !appengine -// +build !appengine - -package internal - -import ( - "bytes" - "context" - "errors" - "fmt" - "io/ioutil" - "log" - "net" - "net/http" - "net/url" - "os" - "runtime" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/golang/protobuf/proto" - - basepb "google.golang.org/appengine/internal/base" - logpb "google.golang.org/appengine/internal/log" - remotepb "google.golang.org/appengine/internal/remote_api" -) - -const ( - apiPath = "/rpc_http" -) - -var ( - // Incoming headers. - ticketHeader = http.CanonicalHeaderKey("X-AppEngine-API-Ticket") - dapperHeader = http.CanonicalHeaderKey("X-Google-DapperTraceInfo") - traceHeader = http.CanonicalHeaderKey("X-Cloud-Trace-Context") - curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace") - userIPHeader = http.CanonicalHeaderKey("X-AppEngine-User-IP") - remoteAddrHeader = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr") - devRequestIdHeader = http.CanonicalHeaderKey("X-Appengine-Dev-Request-Id") - - // Outgoing headers. - apiEndpointHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint") - apiEndpointHeaderValue = []string{"app-engine-apis"} - apiMethodHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Method") - apiMethodHeaderValue = []string{"/VMRemoteAPI.CallRemoteAPI"} - apiDeadlineHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Deadline") - apiContentType = http.CanonicalHeaderKey("Content-Type") - apiContentTypeValue = []string{"application/octet-stream"} - logFlushHeader = http.CanonicalHeaderKey("X-AppEngine-Log-Flush-Count") - - apiHTTPClient = &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: limitDial, - MaxIdleConns: 1000, - MaxIdleConnsPerHost: 10000, - IdleConnTimeout: 90 * time.Second, - }, - } -) - -func apiURL(ctx context.Context) *url.URL { - host, port := "appengine.googleapis.internal", "10001" - if h := os.Getenv("API_HOST"); h != "" { - host = h - } - if hostOverride := ctx.Value(apiHostOverrideKey); hostOverride != nil { - host = hostOverride.(string) - } - if p := os.Getenv("API_PORT"); p != "" { - port = p - } - if portOverride := ctx.Value(apiPortOverrideKey); portOverride != nil { - port = portOverride.(string) - } - return &url.URL{ - Scheme: "http", - Host: host + ":" + port, - Path: apiPath, - } -} - -// Middleware wraps an http handler so that it can make GAE API calls -func Middleware(next http.Handler) http.Handler { - return handleHTTPMiddleware(executeRequestSafelyMiddleware(next)) -} - -func handleHTTPMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - c := &aeContext{ - req: r, - outHeader: w.Header(), - } - r = r.WithContext(withContext(r.Context(), c)) - c.req = r - - stopFlushing := make(chan int) - - // Patch up RemoteAddr so it looks reasonable. - if addr := r.Header.Get(userIPHeader); addr != "" { - r.RemoteAddr = addr - } else if addr = r.Header.Get(remoteAddrHeader); addr != "" { - r.RemoteAddr = addr - } else { - // Should not normally reach here, but pick a sensible default anyway. - r.RemoteAddr = "127.0.0.1" - } - // The address in the headers will most likely be of these forms: - // 123.123.123.123 - // 2001:db8::1 - // net/http.Request.RemoteAddr is specified to be in "IP:port" form. - if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { - // Assume the remote address is only a host; add a default port. - r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80") - } - - if logToLogservice() { - // Start goroutine responsible for flushing app logs. - // This is done after adding c to ctx.m (and stopped before removing it) - // because flushing logs requires making an API call. - go c.logFlusher(stopFlushing) - } - - next.ServeHTTP(c, r) - c.outHeader = nil // make sure header changes aren't respected any more - - flushed := make(chan struct{}) - if logToLogservice() { - stopFlushing <- 1 // any logging beyond this point will be dropped - - // Flush any pending logs asynchronously. - c.pendingLogs.Lock() - flushes := c.pendingLogs.flushes - if len(c.pendingLogs.lines) > 0 { - flushes++ - } - c.pendingLogs.Unlock() - go func() { - defer close(flushed) - // Force a log flush, because with very short requests we - // may not ever flush logs. - c.flushLog(true) - }() - w.Header().Set(logFlushHeader, strconv.Itoa(flushes)) - } - - // Avoid nil Write call if c.Write is never called. - if c.outCode != 0 { - w.WriteHeader(c.outCode) - } - if c.outBody != nil { - w.Write(c.outBody) - } - if logToLogservice() { - // Wait for the last flush to complete before returning, - // otherwise the security ticket will not be valid. - <-flushed - } - }) -} - -func executeRequestSafelyMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - defer func() { - if x := recover(); x != nil { - c := w.(*aeContext) - logf(c, 4, "%s", renderPanic(x)) // 4 == critical - c.outCode = 500 - } - }() - - next.ServeHTTP(w, r) - }) -} - -func renderPanic(x interface{}) string { - buf := make([]byte, 16<<10) // 16 KB should be plenty - buf = buf[:runtime.Stack(buf, false)] - - // Remove the first few stack frames: - // this func - // the recover closure in the caller - // That will root the stack trace at the site of the panic. - const ( - skipStart = "internal.renderPanic" - skipFrames = 2 - ) - start := bytes.Index(buf, []byte(skipStart)) - p := start - for i := 0; i < skipFrames*2 && p+1 < len(buf); i++ { - p = bytes.IndexByte(buf[p+1:], '\n') + p + 1 - if p < 0 { - break - } - } - if p >= 0 { - // buf[start:p+1] is the block to remove. - // Copy buf[p+1:] over buf[start:] and shrink buf. - copy(buf[start:], buf[p+1:]) - buf = buf[:len(buf)-(p+1-start)] - } - - // Add panic heading. - head := fmt.Sprintf("panic: %v\n\n", x) - if len(head) > len(buf) { - // Extremely unlikely to happen. - return head - } - copy(buf[len(head):], buf) - copy(buf, head) - - return string(buf) -} - -// aeContext represents the aeContext of an in-flight HTTP request. -// It implements the appengine.Context and http.ResponseWriter interfaces. -type aeContext struct { - req *http.Request - - outCode int - outHeader http.Header - outBody []byte - - pendingLogs struct { - sync.Mutex - lines []*logpb.UserAppLogLine - flushes int - } -} - -var contextKey = "holds a *context" - -// jointContext joins two contexts in a superficial way. -// It takes values and timeouts from a base context, and only values from another context. -type jointContext struct { - base context.Context - valuesOnly context.Context -} - -func (c jointContext) Deadline() (time.Time, bool) { - return c.base.Deadline() -} - -func (c jointContext) Done() <-chan struct{} { - return c.base.Done() -} - -func (c jointContext) Err() error { - return c.base.Err() -} - -func (c jointContext) Value(key interface{}) interface{} { - if val := c.base.Value(key); val != nil { - return val - } - return c.valuesOnly.Value(key) -} - -// fromContext returns the App Engine context or nil if ctx is not -// derived from an App Engine context. -func fromContext(ctx context.Context) *aeContext { - c, _ := ctx.Value(&contextKey).(*aeContext) - return c -} - -func withContext(parent context.Context, c *aeContext) context.Context { - ctx := context.WithValue(parent, &contextKey, c) - if ns := c.req.Header.Get(curNamespaceHeader); ns != "" { - ctx = withNamespace(ctx, ns) - } - return ctx -} - -func toContext(c *aeContext) context.Context { - return withContext(context.Background(), c) -} - -func IncomingHeaders(ctx context.Context) http.Header { - if c := fromContext(ctx); c != nil { - return c.req.Header - } - return nil -} - -func ReqContext(req *http.Request) context.Context { - return req.Context() -} - -func WithContext(parent context.Context, req *http.Request) context.Context { - return jointContext{ - base: parent, - valuesOnly: req.Context(), - } -} - -// RegisterTestRequest registers the HTTP request req for testing, such that -// any API calls are sent to the provided URL. -// It should only be used by aetest package. -func RegisterTestRequest(req *http.Request, apiURL *url.URL, appID string) *http.Request { - ctx := req.Context() - ctx = withAPIHostOverride(ctx, apiURL.Hostname()) - ctx = withAPIPortOverride(ctx, apiURL.Port()) - ctx = WithAppIDOverride(ctx, appID) - - // use the unregistered request as a placeholder so that withContext can read the headers - c := &aeContext{req: req} - c.req = req.WithContext(withContext(ctx, c)) - return c.req -} - -var errTimeout = &CallError{ - Detail: "Deadline exceeded", - Code: int32(remotepb.RpcError_CANCELLED), - Timeout: true, -} - -func (c *aeContext) Header() http.Header { return c.outHeader } - -// Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status -// codes do not permit a response body (nor response entity headers such as -// Content-Length, Content-Type, etc). -func bodyAllowedForStatus(status int) bool { - switch { - case status >= 100 && status <= 199: - return false - case status == 204: - return false - case status == 304: - return false - } - return true -} - -func (c *aeContext) Write(b []byte) (int, error) { - if c.outCode == 0 { - c.WriteHeader(http.StatusOK) - } - if len(b) > 0 && !bodyAllowedForStatus(c.outCode) { - return 0, http.ErrBodyNotAllowed - } - c.outBody = append(c.outBody, b...) - return len(b), nil -} - -func (c *aeContext) WriteHeader(code int) { - if c.outCode != 0 { - logf(c, 3, "WriteHeader called multiple times on request.") // error level - return - } - c.outCode = code -} - -func post(ctx context.Context, body []byte, timeout time.Duration) (b []byte, err error) { - apiURL := apiURL(ctx) - hreq := &http.Request{ - Method: "POST", - URL: apiURL, - Header: http.Header{ - apiEndpointHeader: apiEndpointHeaderValue, - apiMethodHeader: apiMethodHeaderValue, - apiContentType: apiContentTypeValue, - apiDeadlineHeader: []string{strconv.FormatFloat(timeout.Seconds(), 'f', -1, 64)}, - }, - Body: ioutil.NopCloser(bytes.NewReader(body)), - ContentLength: int64(len(body)), - Host: apiURL.Host, - } - c := fromContext(ctx) - if c != nil { - if info := c.req.Header.Get(dapperHeader); info != "" { - hreq.Header.Set(dapperHeader, info) - } - if info := c.req.Header.Get(traceHeader); info != "" { - hreq.Header.Set(traceHeader, info) - } - } - - tr := apiHTTPClient.Transport.(*http.Transport) - - var timedOut int32 // atomic; set to 1 if timed out - t := time.AfterFunc(timeout, func() { - atomic.StoreInt32(&timedOut, 1) - tr.CancelRequest(hreq) - }) - defer t.Stop() - defer func() { - // Check if timeout was exceeded. - if atomic.LoadInt32(&timedOut) != 0 { - err = errTimeout - } - }() - - hresp, err := apiHTTPClient.Do(hreq) - if err != nil { - return nil, &CallError{ - Detail: fmt.Sprintf("service bridge HTTP failed: %v", err), - Code: int32(remotepb.RpcError_UNKNOWN), - } - } - defer hresp.Body.Close() - hrespBody, err := ioutil.ReadAll(hresp.Body) - if hresp.StatusCode != 200 { - return nil, &CallError{ - Detail: fmt.Sprintf("service bridge returned HTTP %d (%q)", hresp.StatusCode, hrespBody), - Code: int32(remotepb.RpcError_UNKNOWN), - } - } - if err != nil { - return nil, &CallError{ - Detail: fmt.Sprintf("service bridge response bad: %v", err), - Code: int32(remotepb.RpcError_UNKNOWN), - } - } - return hrespBody, nil -} - -func Call(ctx context.Context, service, method string, in, out proto.Message) error { - if ns := NamespaceFromContext(ctx); ns != "" { - if fn, ok := NamespaceMods[service]; ok { - fn(in, ns) - } - } - - if f, ctx, ok := callOverrideFromContext(ctx); ok { - return f(ctx, service, method, in, out) - } - - // Handle already-done contexts quickly. - select { - case <-ctx.Done(): - return ctx.Err() - default: - } - - c := fromContext(ctx) - - // Apply transaction modifications if we're in a transaction. - if t := transactionFromContext(ctx); t != nil { - if t.finished { - return errors.New("transaction aeContext has expired") - } - applyTransaction(in, &t.transaction) - } - - // Default RPC timeout is 60s. - timeout := 60 * time.Second - if deadline, ok := ctx.Deadline(); ok { - timeout = deadline.Sub(time.Now()) - } - - data, err := proto.Marshal(in) - if err != nil { - return err - } - - ticket := "" - if c != nil { - ticket = c.req.Header.Get(ticketHeader) - if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" { - ticket = dri - } - } - req := &remotepb.Request{ - ServiceName: &service, - Method: &method, - Request: data, - RequestId: &ticket, - } - hreqBody, err := proto.Marshal(req) - if err != nil { - return err - } - - hrespBody, err := post(ctx, hreqBody, timeout) - if err != nil { - return err - } - - res := &remotepb.Response{} - if err := proto.Unmarshal(hrespBody, res); err != nil { - return err - } - if res.RpcError != nil { - ce := &CallError{ - Detail: res.RpcError.GetDetail(), - Code: *res.RpcError.Code, - } - switch remotepb.RpcError_ErrorCode(ce.Code) { - case remotepb.RpcError_CANCELLED, remotepb.RpcError_DEADLINE_EXCEEDED: - ce.Timeout = true - } - return ce - } - if res.ApplicationError != nil { - return &APIError{ - Service: *req.ServiceName, - Detail: res.ApplicationError.GetDetail(), - Code: *res.ApplicationError.Code, - } - } - if res.Exception != nil || res.JavaException != nil { - // This shouldn't happen, but let's be defensive. - return &CallError{ - Detail: "service bridge returned exception", - Code: int32(remotepb.RpcError_UNKNOWN), - } - } - return proto.Unmarshal(res.Response, out) -} - -func (c *aeContext) Request() *http.Request { - return c.req -} - -func (c *aeContext) addLogLine(ll *logpb.UserAppLogLine) { - // Truncate long log lines. - // TODO(dsymonds): Check if this is still necessary. - const lim = 8 << 10 - if len(*ll.Message) > lim { - suffix := fmt.Sprintf("...(length %d)", len(*ll.Message)) - ll.Message = proto.String((*ll.Message)[:lim-len(suffix)] + suffix) - } - - c.pendingLogs.Lock() - c.pendingLogs.lines = append(c.pendingLogs.lines, ll) - c.pendingLogs.Unlock() -} - -var logLevelName = map[int64]string{ - 0: "DEBUG", - 1: "INFO", - 2: "WARNING", - 3: "ERROR", - 4: "CRITICAL", -} - -func logf(c *aeContext, level int64, format string, args ...interface{}) { - if c == nil { - panic("not an App Engine aeContext") - } - s := fmt.Sprintf(format, args...) - s = strings.TrimRight(s, "\n") // Remove any trailing newline characters. - if logToLogservice() { - c.addLogLine(&logpb.UserAppLogLine{ - TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3), - Level: &level, - Message: &s, - }) - } - // Log to stdout if not deployed - if !IsSecondGen() { - log.Print(logLevelName[level] + ": " + s) - } -} - -// flushLog attempts to flush any pending logs to the appserver. -// It should not be called concurrently. -func (c *aeContext) flushLog(force bool) (flushed bool) { - c.pendingLogs.Lock() - // Grab up to 30 MB. We can get away with up to 32 MB, but let's be cautious. - n, rem := 0, 30<<20 - for ; n < len(c.pendingLogs.lines); n++ { - ll := c.pendingLogs.lines[n] - // Each log line will require about 3 bytes of overhead. - nb := proto.Size(ll) + 3 - if nb > rem { - break - } - rem -= nb - } - lines := c.pendingLogs.lines[:n] - c.pendingLogs.lines = c.pendingLogs.lines[n:] - c.pendingLogs.Unlock() - - if len(lines) == 0 && !force { - // Nothing to flush. - return false - } - - rescueLogs := false - defer func() { - if rescueLogs { - c.pendingLogs.Lock() - c.pendingLogs.lines = append(lines, c.pendingLogs.lines...) - c.pendingLogs.Unlock() - } - }() - - buf, err := proto.Marshal(&logpb.UserAppLogGroup{ - LogLine: lines, - }) - if err != nil { - log.Printf("internal.flushLog: marshaling UserAppLogGroup: %v", err) - rescueLogs = true - return false - } - - req := &logpb.FlushRequest{ - Logs: buf, - } - res := &basepb.VoidProto{} - c.pendingLogs.Lock() - c.pendingLogs.flushes++ - c.pendingLogs.Unlock() - if err := Call(toContext(c), "logservice", "Flush", req, res); err != nil { - log.Printf("internal.flushLog: Flush RPC: %v", err) - rescueLogs = true - return false - } - return true -} - -const ( - // Log flushing parameters. - flushInterval = 1 * time.Second - forceFlushInterval = 60 * time.Second -) - -func (c *aeContext) logFlusher(stop <-chan int) { - lastFlush := time.Now() - tick := time.NewTicker(flushInterval) - for { - select { - case <-stop: - // Request finished. - tick.Stop() - return - case <-tick.C: - force := time.Now().Sub(lastFlush) > forceFlushInterval - if c.flushLog(force) { - lastFlush = time.Now() - } - } - } -} - -func ContextForTesting(req *http.Request) context.Context { - return toContext(&aeContext{req: req}) -} - -func logToLogservice() bool { - // TODO: replace logservice with json structured logs to $LOG_DIR/app.log.json - // where $LOG_DIR is /var/log in prod and some tmpdir in dev - return os.Getenv("LOG_TO_LOGSERVICE") != "0" -} diff --git a/vendor/google.golang.org/appengine/internal/api_classic.go b/vendor/google.golang.org/appengine/internal/api_classic.go deleted file mode 100644 index 87c33c79..00000000 --- a/vendor/google.golang.org/appengine/internal/api_classic.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2015 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build appengine -// +build appengine - -package internal - -import ( - "context" - "errors" - "fmt" - "net/http" - "time" - - "appengine" - "appengine_internal" - basepb "appengine_internal/base" - - "github.com/golang/protobuf/proto" -) - -var contextKey = "holds an appengine.Context" - -// fromContext returns the App Engine context or nil if ctx is not -// derived from an App Engine context. -func fromContext(ctx context.Context) appengine.Context { - c, _ := ctx.Value(&contextKey).(appengine.Context) - return c -} - -// This is only for classic App Engine adapters. -func ClassicContextFromContext(ctx context.Context) (appengine.Context, error) { - c := fromContext(ctx) - if c == nil { - return nil, errNotAppEngineContext - } - return c, nil -} - -func withContext(parent context.Context, c appengine.Context) context.Context { - ctx := context.WithValue(parent, &contextKey, c) - - s := &basepb.StringProto{} - c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil) - if ns := s.GetValue(); ns != "" { - ctx = NamespacedContext(ctx, ns) - } - - return ctx -} - -func IncomingHeaders(ctx context.Context) http.Header { - if c := fromContext(ctx); c != nil { - if req, ok := c.Request().(*http.Request); ok { - return req.Header - } - } - return nil -} - -func ReqContext(req *http.Request) context.Context { - return WithContext(context.Background(), req) -} - -func WithContext(parent context.Context, req *http.Request) context.Context { - c := appengine.NewContext(req) - return withContext(parent, c) -} - -type testingContext struct { - appengine.Context - - req *http.Request -} - -func (t *testingContext) FullyQualifiedAppID() string { return "dev~testcontext" } -func (t *testingContext) Call(service, method string, _, _ appengine_internal.ProtoMessage, _ *appengine_internal.CallOptions) error { - if service == "__go__" && method == "GetNamespace" { - return nil - } - return fmt.Errorf("testingContext: unsupported Call") -} -func (t *testingContext) Request() interface{} { return t.req } - -func ContextForTesting(req *http.Request) context.Context { - return withContext(context.Background(), &testingContext{req: req}) -} - -func Call(ctx context.Context, service, method string, in, out proto.Message) error { - if ns := NamespaceFromContext(ctx); ns != "" { - if fn, ok := NamespaceMods[service]; ok { - fn(in, ns) - } - } - - if f, ctx, ok := callOverrideFromContext(ctx); ok { - return f(ctx, service, method, in, out) - } - - // Handle already-done contexts quickly. - select { - case <-ctx.Done(): - return ctx.Err() - default: - } - - c := fromContext(ctx) - if c == nil { - // Give a good error message rather than a panic lower down. - return errNotAppEngineContext - } - - // Apply transaction modifications if we're in a transaction. - if t := transactionFromContext(ctx); t != nil { - if t.finished { - return errors.New("transaction context has expired") - } - applyTransaction(in, &t.transaction) - } - - var opts *appengine_internal.CallOptions - if d, ok := ctx.Deadline(); ok { - opts = &appengine_internal.CallOptions{ - Timeout: d.Sub(time.Now()), - } - } - - err := c.Call(service, method, in, out, opts) - switch v := err.(type) { - case *appengine_internal.APIError: - return &APIError{ - Service: v.Service, - Detail: v.Detail, - Code: v.Code, - } - case *appengine_internal.CallError: - return &CallError{ - Detail: v.Detail, - Code: v.Code, - Timeout: v.Timeout, - } - } - return err -} - -func Middleware(next http.Handler) http.Handler { - panic("Middleware called; this should be impossible") -} - -func logf(c appengine.Context, level int64, format string, args ...interface{}) { - var fn func(format string, args ...interface{}) - switch level { - case 0: - fn = c.Debugf - case 1: - fn = c.Infof - case 2: - fn = c.Warningf - case 3: - fn = c.Errorf - case 4: - fn = c.Criticalf - default: - // This shouldn't happen. - fn = c.Criticalf - } - fn(format, args...) -} diff --git a/vendor/google.golang.org/appengine/internal/api_common.go b/vendor/google.golang.org/appengine/internal/api_common.go deleted file mode 100644 index 5b95c13d..00000000 --- a/vendor/google.golang.org/appengine/internal/api_common.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2015 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package internal - -import ( - "context" - "errors" - "os" - - "github.com/golang/protobuf/proto" -) - -type ctxKey string - -func (c ctxKey) String() string { - return "appengine context key: " + string(c) -} - -var errNotAppEngineContext = errors.New("not an App Engine context") - -type CallOverrideFunc func(ctx context.Context, service, method string, in, out proto.Message) error - -var callOverrideKey = "holds []CallOverrideFunc" - -func WithCallOverride(ctx context.Context, f CallOverrideFunc) context.Context { - // We avoid appending to any existing call override - // so we don't risk overwriting a popped stack below. - var cofs []CallOverrideFunc - if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok { - cofs = append(cofs, uf...) - } - cofs = append(cofs, f) - return context.WithValue(ctx, &callOverrideKey, cofs) -} - -func callOverrideFromContext(ctx context.Context) (CallOverrideFunc, context.Context, bool) { - cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc) - if len(cofs) == 0 { - return nil, nil, false - } - // We found a list of overrides; grab the last, and reconstitute a - // context that will hide it. - f := cofs[len(cofs)-1] - ctx = context.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1]) - return f, ctx, true -} - -type logOverrideFunc func(level int64, format string, args ...interface{}) - -var logOverrideKey = "holds a logOverrideFunc" - -func WithLogOverride(ctx context.Context, f logOverrideFunc) context.Context { - return context.WithValue(ctx, &logOverrideKey, f) -} - -var appIDOverrideKey = "holds a string, being the full app ID" - -func WithAppIDOverride(ctx context.Context, appID string) context.Context { - return context.WithValue(ctx, &appIDOverrideKey, appID) -} - -var apiHostOverrideKey = ctxKey("holds a string, being the alternate API_HOST") - -func withAPIHostOverride(ctx context.Context, apiHost string) context.Context { - return context.WithValue(ctx, apiHostOverrideKey, apiHost) -} - -var apiPortOverrideKey = ctxKey("holds a string, being the alternate API_PORT") - -func withAPIPortOverride(ctx context.Context, apiPort string) context.Context { - return context.WithValue(ctx, apiPortOverrideKey, apiPort) -} - -var namespaceKey = "holds the namespace string" - -func withNamespace(ctx context.Context, ns string) context.Context { - return context.WithValue(ctx, &namespaceKey, ns) -} - -func NamespaceFromContext(ctx context.Context) string { - // If there's no namespace, return the empty string. - ns, _ := ctx.Value(&namespaceKey).(string) - return ns -} - -// FullyQualifiedAppID returns the fully-qualified application ID. -// This may contain a partition prefix (e.g. "s~" for High Replication apps), -// or a domain prefix (e.g. "example.com:"). -func FullyQualifiedAppID(ctx context.Context) string { - if id, ok := ctx.Value(&appIDOverrideKey).(string); ok { - return id - } - return fullyQualifiedAppID(ctx) -} - -func Logf(ctx context.Context, level int64, format string, args ...interface{}) { - if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok { - f(level, format, args...) - return - } - c := fromContext(ctx) - if c == nil { - panic(errNotAppEngineContext) - } - logf(c, level, format, args...) -} - -// NamespacedContext wraps a Context to support namespaces. -func NamespacedContext(ctx context.Context, namespace string) context.Context { - return withNamespace(ctx, namespace) -} - -// SetTestEnv sets the env variables for testing background ticket in Flex. -func SetTestEnv() func() { - var environ = []struct { - key, value string - }{ - {"GAE_LONG_APP_ID", "my-app-id"}, - {"GAE_MINOR_VERSION", "067924799508853122"}, - {"GAE_MODULE_INSTANCE", "0"}, - {"GAE_MODULE_NAME", "default"}, - {"GAE_MODULE_VERSION", "20150612t184001"}, - } - - for _, v := range environ { - old := os.Getenv(v.key) - os.Setenv(v.key, v.value) - v.value = old - } - return func() { // Restore old environment after the test completes. - for _, v := range environ { - if v.value == "" { - os.Unsetenv(v.key) - continue - } - os.Setenv(v.key, v.value) - } - } -} diff --git a/vendor/google.golang.org/appengine/internal/app_id.go b/vendor/google.golang.org/appengine/internal/app_id.go deleted file mode 100644 index 11df8c07..00000000 --- a/vendor/google.golang.org/appengine/internal/app_id.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package internal - -import ( - "strings" -) - -func parseFullAppID(appid string) (partition, domain, displayID string) { - if i := strings.Index(appid, "~"); i != -1 { - partition, appid = appid[:i], appid[i+1:] - } - if i := strings.Index(appid, ":"); i != -1 { - domain, appid = appid[:i], appid[i+1:] - } - return partition, domain, appid -} - -// appID returns "appid" or "domain.com:appid". -func appID(fullAppID string) string { - _, dom, dis := parseFullAppID(fullAppID) - if dom != "" { - return dom + ":" + dis - } - return dis -} diff --git a/vendor/google.golang.org/appengine/internal/base/api_base.pb.go b/vendor/google.golang.org/appengine/internal/base/api_base.pb.go deleted file mode 100644 index db4777e6..00000000 --- a/vendor/google.golang.org/appengine/internal/base/api_base.pb.go +++ /dev/null @@ -1,308 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google.golang.org/appengine/internal/base/api_base.proto - -package base - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type StringProto struct { - Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *StringProto) Reset() { *m = StringProto{} } -func (m *StringProto) String() string { return proto.CompactTextString(m) } -func (*StringProto) ProtoMessage() {} -func (*StringProto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{0} -} -func (m *StringProto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StringProto.Unmarshal(m, b) -} -func (m *StringProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StringProto.Marshal(b, m, deterministic) -} -func (dst *StringProto) XXX_Merge(src proto.Message) { - xxx_messageInfo_StringProto.Merge(dst, src) -} -func (m *StringProto) XXX_Size() int { - return xxx_messageInfo_StringProto.Size(m) -} -func (m *StringProto) XXX_DiscardUnknown() { - xxx_messageInfo_StringProto.DiscardUnknown(m) -} - -var xxx_messageInfo_StringProto proto.InternalMessageInfo - -func (m *StringProto) GetValue() string { - if m != nil && m.Value != nil { - return *m.Value - } - return "" -} - -type Integer32Proto struct { - Value *int32 `protobuf:"varint,1,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Integer32Proto) Reset() { *m = Integer32Proto{} } -func (m *Integer32Proto) String() string { return proto.CompactTextString(m) } -func (*Integer32Proto) ProtoMessage() {} -func (*Integer32Proto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{1} -} -func (m *Integer32Proto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Integer32Proto.Unmarshal(m, b) -} -func (m *Integer32Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Integer32Proto.Marshal(b, m, deterministic) -} -func (dst *Integer32Proto) XXX_Merge(src proto.Message) { - xxx_messageInfo_Integer32Proto.Merge(dst, src) -} -func (m *Integer32Proto) XXX_Size() int { - return xxx_messageInfo_Integer32Proto.Size(m) -} -func (m *Integer32Proto) XXX_DiscardUnknown() { - xxx_messageInfo_Integer32Proto.DiscardUnknown(m) -} - -var xxx_messageInfo_Integer32Proto proto.InternalMessageInfo - -func (m *Integer32Proto) GetValue() int32 { - if m != nil && m.Value != nil { - return *m.Value - } - return 0 -} - -type Integer64Proto struct { - Value *int64 `protobuf:"varint,1,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Integer64Proto) Reset() { *m = Integer64Proto{} } -func (m *Integer64Proto) String() string { return proto.CompactTextString(m) } -func (*Integer64Proto) ProtoMessage() {} -func (*Integer64Proto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{2} -} -func (m *Integer64Proto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Integer64Proto.Unmarshal(m, b) -} -func (m *Integer64Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Integer64Proto.Marshal(b, m, deterministic) -} -func (dst *Integer64Proto) XXX_Merge(src proto.Message) { - xxx_messageInfo_Integer64Proto.Merge(dst, src) -} -func (m *Integer64Proto) XXX_Size() int { - return xxx_messageInfo_Integer64Proto.Size(m) -} -func (m *Integer64Proto) XXX_DiscardUnknown() { - xxx_messageInfo_Integer64Proto.DiscardUnknown(m) -} - -var xxx_messageInfo_Integer64Proto proto.InternalMessageInfo - -func (m *Integer64Proto) GetValue() int64 { - if m != nil && m.Value != nil { - return *m.Value - } - return 0 -} - -type BoolProto struct { - Value *bool `protobuf:"varint,1,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *BoolProto) Reset() { *m = BoolProto{} } -func (m *BoolProto) String() string { return proto.CompactTextString(m) } -func (*BoolProto) ProtoMessage() {} -func (*BoolProto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{3} -} -func (m *BoolProto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BoolProto.Unmarshal(m, b) -} -func (m *BoolProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BoolProto.Marshal(b, m, deterministic) -} -func (dst *BoolProto) XXX_Merge(src proto.Message) { - xxx_messageInfo_BoolProto.Merge(dst, src) -} -func (m *BoolProto) XXX_Size() int { - return xxx_messageInfo_BoolProto.Size(m) -} -func (m *BoolProto) XXX_DiscardUnknown() { - xxx_messageInfo_BoolProto.DiscardUnknown(m) -} - -var xxx_messageInfo_BoolProto proto.InternalMessageInfo - -func (m *BoolProto) GetValue() bool { - if m != nil && m.Value != nil { - return *m.Value - } - return false -} - -type DoubleProto struct { - Value *float64 `protobuf:"fixed64,1,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DoubleProto) Reset() { *m = DoubleProto{} } -func (m *DoubleProto) String() string { return proto.CompactTextString(m) } -func (*DoubleProto) ProtoMessage() {} -func (*DoubleProto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{4} -} -func (m *DoubleProto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DoubleProto.Unmarshal(m, b) -} -func (m *DoubleProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DoubleProto.Marshal(b, m, deterministic) -} -func (dst *DoubleProto) XXX_Merge(src proto.Message) { - xxx_messageInfo_DoubleProto.Merge(dst, src) -} -func (m *DoubleProto) XXX_Size() int { - return xxx_messageInfo_DoubleProto.Size(m) -} -func (m *DoubleProto) XXX_DiscardUnknown() { - xxx_messageInfo_DoubleProto.DiscardUnknown(m) -} - -var xxx_messageInfo_DoubleProto proto.InternalMessageInfo - -func (m *DoubleProto) GetValue() float64 { - if m != nil && m.Value != nil { - return *m.Value - } - return 0 -} - -type BytesProto struct { - Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *BytesProto) Reset() { *m = BytesProto{} } -func (m *BytesProto) String() string { return proto.CompactTextString(m) } -func (*BytesProto) ProtoMessage() {} -func (*BytesProto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{5} -} -func (m *BytesProto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BytesProto.Unmarshal(m, b) -} -func (m *BytesProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BytesProto.Marshal(b, m, deterministic) -} -func (dst *BytesProto) XXX_Merge(src proto.Message) { - xxx_messageInfo_BytesProto.Merge(dst, src) -} -func (m *BytesProto) XXX_Size() int { - return xxx_messageInfo_BytesProto.Size(m) -} -func (m *BytesProto) XXX_DiscardUnknown() { - xxx_messageInfo_BytesProto.DiscardUnknown(m) -} - -var xxx_messageInfo_BytesProto proto.InternalMessageInfo - -func (m *BytesProto) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -type VoidProto struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *VoidProto) Reset() { *m = VoidProto{} } -func (m *VoidProto) String() string { return proto.CompactTextString(m) } -func (*VoidProto) ProtoMessage() {} -func (*VoidProto) Descriptor() ([]byte, []int) { - return fileDescriptor_api_base_9d49f8792e0c1140, []int{6} -} -func (m *VoidProto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_VoidProto.Unmarshal(m, b) -} -func (m *VoidProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_VoidProto.Marshal(b, m, deterministic) -} -func (dst *VoidProto) XXX_Merge(src proto.Message) { - xxx_messageInfo_VoidProto.Merge(dst, src) -} -func (m *VoidProto) XXX_Size() int { - return xxx_messageInfo_VoidProto.Size(m) -} -func (m *VoidProto) XXX_DiscardUnknown() { - xxx_messageInfo_VoidProto.DiscardUnknown(m) -} - -var xxx_messageInfo_VoidProto proto.InternalMessageInfo - -func init() { - proto.RegisterType((*StringProto)(nil), "appengine.base.StringProto") - proto.RegisterType((*Integer32Proto)(nil), "appengine.base.Integer32Proto") - proto.RegisterType((*Integer64Proto)(nil), "appengine.base.Integer64Proto") - proto.RegisterType((*BoolProto)(nil), "appengine.base.BoolProto") - proto.RegisterType((*DoubleProto)(nil), "appengine.base.DoubleProto") - proto.RegisterType((*BytesProto)(nil), "appengine.base.BytesProto") - proto.RegisterType((*VoidProto)(nil), "appengine.base.VoidProto") -} - -func init() { - proto.RegisterFile("google.golang.org/appengine/internal/base/api_base.proto", fileDescriptor_api_base_9d49f8792e0c1140) -} - -var fileDescriptor_api_base_9d49f8792e0c1140 = []byte{ - // 199 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0xcf, 0x3f, 0x4b, 0xc6, 0x30, - 0x10, 0x06, 0x70, 0x5a, 0xad, 0xb4, 0x57, 0xe9, 0x20, 0x0e, 0x1d, 0xb5, 0x05, 0x71, 0x4a, 0x40, - 0x45, 0x9c, 0x83, 0x8b, 0x9b, 0x28, 0x38, 0xb8, 0x48, 0x8a, 0xc7, 0x11, 0x08, 0xb9, 0x90, 0xa6, - 0x82, 0xdf, 0x5e, 0xda, 0xd2, 0xfa, 0xc2, 0x9b, 0xed, 0xfe, 0xfc, 0xe0, 0xe1, 0x81, 0x27, 0x62, - 0x26, 0x8b, 0x82, 0xd8, 0x6a, 0x47, 0x82, 0x03, 0x49, 0xed, 0x3d, 0x3a, 0x32, 0x0e, 0xa5, 0x71, - 0x11, 0x83, 0xd3, 0x56, 0x0e, 0x7a, 0x44, 0xa9, 0xbd, 0xf9, 0x9a, 0x07, 0xe1, 0x03, 0x47, 0xbe, - 0x68, 0x76, 0x27, 0xe6, 0x6b, 0xd7, 0x43, 0xfd, 0x1e, 0x83, 0x71, 0xf4, 0xba, 0xbc, 0x2f, 0xa1, - 0xf8, 0xd1, 0x76, 0xc2, 0x36, 0xbb, 0xca, 0x6f, 0xab, 0xb7, 0x75, 0xe9, 0x6e, 0xa0, 0x79, 0x71, - 0x11, 0x09, 0xc3, 0xfd, 0x5d, 0xc2, 0x15, 0xc7, 0xee, 0xf1, 0x21, 0xe1, 0x4e, 0x36, 0x77, 0x0d, - 0x95, 0x62, 0xb6, 0x09, 0x52, 0x6e, 0xa4, 0x87, 0xfa, 0x99, 0xa7, 0xc1, 0x62, 0x02, 0x65, 0xff, - 0x79, 0xa0, 0x7e, 0x23, 0x8e, 0xab, 0x69, 0x0f, 0xcd, 0xb9, 0xca, 0xcb, 0xdd, 0xd5, 0x50, 0x7d, - 0xb0, 0xf9, 0x5e, 0x98, 0x3a, 0xfb, 0x3c, 0x9d, 0x9b, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xba, - 0x37, 0x25, 0xea, 0x44, 0x01, 0x00, 0x00, -} diff --git a/vendor/google.golang.org/appengine/internal/base/api_base.proto b/vendor/google.golang.org/appengine/internal/base/api_base.proto deleted file mode 100644 index 56cd7a3c..00000000 --- a/vendor/google.golang.org/appengine/internal/base/api_base.proto +++ /dev/null @@ -1,33 +0,0 @@ -// Built-in base types for API calls. Primarily useful as return types. - -syntax = "proto2"; -option go_package = "base"; - -package appengine.base; - -message StringProto { - required string value = 1; -} - -message Integer32Proto { - required int32 value = 1; -} - -message Integer64Proto { - required int64 value = 1; -} - -message BoolProto { - required bool value = 1; -} - -message DoubleProto { - required double value = 1; -} - -message BytesProto { - required bytes value = 1 [ctype=CORD]; -} - -message VoidProto { -} diff --git a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go deleted file mode 100644 index 2fb74828..00000000 --- a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go +++ /dev/null @@ -1,4367 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google.golang.org/appengine/internal/datastore/datastore_v3.proto - -package datastore - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type Property_Meaning int32 - -const ( - Property_NO_MEANING Property_Meaning = 0 - Property_BLOB Property_Meaning = 14 - Property_TEXT Property_Meaning = 15 - Property_BYTESTRING Property_Meaning = 16 - Property_ATOM_CATEGORY Property_Meaning = 1 - Property_ATOM_LINK Property_Meaning = 2 - Property_ATOM_TITLE Property_Meaning = 3 - Property_ATOM_CONTENT Property_Meaning = 4 - Property_ATOM_SUMMARY Property_Meaning = 5 - Property_ATOM_AUTHOR Property_Meaning = 6 - Property_GD_WHEN Property_Meaning = 7 - Property_GD_EMAIL Property_Meaning = 8 - Property_GEORSS_POINT Property_Meaning = 9 - Property_GD_IM Property_Meaning = 10 - Property_GD_PHONENUMBER Property_Meaning = 11 - Property_GD_POSTALADDRESS Property_Meaning = 12 - Property_GD_RATING Property_Meaning = 13 - Property_BLOBKEY Property_Meaning = 17 - Property_ENTITY_PROTO Property_Meaning = 19 - Property_INDEX_VALUE Property_Meaning = 18 -) - -var Property_Meaning_name = map[int32]string{ - 0: "NO_MEANING", - 14: "BLOB", - 15: "TEXT", - 16: "BYTESTRING", - 1: "ATOM_CATEGORY", - 2: "ATOM_LINK", - 3: "ATOM_TITLE", - 4: "ATOM_CONTENT", - 5: "ATOM_SUMMARY", - 6: "ATOM_AUTHOR", - 7: "GD_WHEN", - 8: "GD_EMAIL", - 9: "GEORSS_POINT", - 10: "GD_IM", - 11: "GD_PHONENUMBER", - 12: "GD_POSTALADDRESS", - 13: "GD_RATING", - 17: "BLOBKEY", - 19: "ENTITY_PROTO", - 18: "INDEX_VALUE", -} -var Property_Meaning_value = map[string]int32{ - "NO_MEANING": 0, - "BLOB": 14, - "TEXT": 15, - "BYTESTRING": 16, - "ATOM_CATEGORY": 1, - "ATOM_LINK": 2, - "ATOM_TITLE": 3, - "ATOM_CONTENT": 4, - "ATOM_SUMMARY": 5, - "ATOM_AUTHOR": 6, - "GD_WHEN": 7, - "GD_EMAIL": 8, - "GEORSS_POINT": 9, - "GD_IM": 10, - "GD_PHONENUMBER": 11, - "GD_POSTALADDRESS": 12, - "GD_RATING": 13, - "BLOBKEY": 17, - "ENTITY_PROTO": 19, - "INDEX_VALUE": 18, -} - -func (x Property_Meaning) Enum() *Property_Meaning { - p := new(Property_Meaning) - *p = x - return p -} -func (x Property_Meaning) String() string { - return proto.EnumName(Property_Meaning_name, int32(x)) -} -func (x *Property_Meaning) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Property_Meaning_value, data, "Property_Meaning") - if err != nil { - return err - } - *x = Property_Meaning(value) - return nil -} -func (Property_Meaning) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 0} -} - -type Property_FtsTokenizationOption int32 - -const ( - Property_HTML Property_FtsTokenizationOption = 1 - Property_ATOM Property_FtsTokenizationOption = 2 -) - -var Property_FtsTokenizationOption_name = map[int32]string{ - 1: "HTML", - 2: "ATOM", -} -var Property_FtsTokenizationOption_value = map[string]int32{ - "HTML": 1, - "ATOM": 2, -} - -func (x Property_FtsTokenizationOption) Enum() *Property_FtsTokenizationOption { - p := new(Property_FtsTokenizationOption) - *p = x - return p -} -func (x Property_FtsTokenizationOption) String() string { - return proto.EnumName(Property_FtsTokenizationOption_name, int32(x)) -} -func (x *Property_FtsTokenizationOption) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Property_FtsTokenizationOption_value, data, "Property_FtsTokenizationOption") - if err != nil { - return err - } - *x = Property_FtsTokenizationOption(value) - return nil -} -func (Property_FtsTokenizationOption) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 1} -} - -type EntityProto_Kind int32 - -const ( - EntityProto_GD_CONTACT EntityProto_Kind = 1 - EntityProto_GD_EVENT EntityProto_Kind = 2 - EntityProto_GD_MESSAGE EntityProto_Kind = 3 -) - -var EntityProto_Kind_name = map[int32]string{ - 1: "GD_CONTACT", - 2: "GD_EVENT", - 3: "GD_MESSAGE", -} -var EntityProto_Kind_value = map[string]int32{ - "GD_CONTACT": 1, - "GD_EVENT": 2, - "GD_MESSAGE": 3, -} - -func (x EntityProto_Kind) Enum() *EntityProto_Kind { - p := new(EntityProto_Kind) - *p = x - return p -} -func (x EntityProto_Kind) String() string { - return proto.EnumName(EntityProto_Kind_name, int32(x)) -} -func (x *EntityProto_Kind) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(EntityProto_Kind_value, data, "EntityProto_Kind") - if err != nil { - return err - } - *x = EntityProto_Kind(value) - return nil -} -func (EntityProto_Kind) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6, 0} -} - -type Index_Property_Direction int32 - -const ( - Index_Property_ASCENDING Index_Property_Direction = 1 - Index_Property_DESCENDING Index_Property_Direction = 2 -) - -var Index_Property_Direction_name = map[int32]string{ - 1: "ASCENDING", - 2: "DESCENDING", -} -var Index_Property_Direction_value = map[string]int32{ - "ASCENDING": 1, - "DESCENDING": 2, -} - -func (x Index_Property_Direction) Enum() *Index_Property_Direction { - p := new(Index_Property_Direction) - *p = x - return p -} -func (x Index_Property_Direction) String() string { - return proto.EnumName(Index_Property_Direction_name, int32(x)) -} -func (x *Index_Property_Direction) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Index_Property_Direction_value, data, "Index_Property_Direction") - if err != nil { - return err - } - *x = Index_Property_Direction(value) - return nil -} -func (Index_Property_Direction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0, 0} -} - -type CompositeIndex_State int32 - -const ( - CompositeIndex_WRITE_ONLY CompositeIndex_State = 1 - CompositeIndex_READ_WRITE CompositeIndex_State = 2 - CompositeIndex_DELETED CompositeIndex_State = 3 - CompositeIndex_ERROR CompositeIndex_State = 4 -) - -var CompositeIndex_State_name = map[int32]string{ - 1: "WRITE_ONLY", - 2: "READ_WRITE", - 3: "DELETED", - 4: "ERROR", -} -var CompositeIndex_State_value = map[string]int32{ - "WRITE_ONLY": 1, - "READ_WRITE": 2, - "DELETED": 3, - "ERROR": 4, -} - -func (x CompositeIndex_State) Enum() *CompositeIndex_State { - p := new(CompositeIndex_State) - *p = x - return p -} -func (x CompositeIndex_State) String() string { - return proto.EnumName(CompositeIndex_State_name, int32(x)) -} -func (x *CompositeIndex_State) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(CompositeIndex_State_value, data, "CompositeIndex_State") - if err != nil { - return err - } - *x = CompositeIndex_State(value) - return nil -} -func (CompositeIndex_State) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9, 0} -} - -type Snapshot_Status int32 - -const ( - Snapshot_INACTIVE Snapshot_Status = 0 - Snapshot_ACTIVE Snapshot_Status = 1 -) - -var Snapshot_Status_name = map[int32]string{ - 0: "INACTIVE", - 1: "ACTIVE", -} -var Snapshot_Status_value = map[string]int32{ - "INACTIVE": 0, - "ACTIVE": 1, -} - -func (x Snapshot_Status) Enum() *Snapshot_Status { - p := new(Snapshot_Status) - *p = x - return p -} -func (x Snapshot_Status) String() string { - return proto.EnumName(Snapshot_Status_name, int32(x)) -} -func (x *Snapshot_Status) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Snapshot_Status_value, data, "Snapshot_Status") - if err != nil { - return err - } - *x = Snapshot_Status(value) - return nil -} -func (Snapshot_Status) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12, 0} -} - -type Query_Hint int32 - -const ( - Query_ORDER_FIRST Query_Hint = 1 - Query_ANCESTOR_FIRST Query_Hint = 2 - Query_FILTER_FIRST Query_Hint = 3 -) - -var Query_Hint_name = map[int32]string{ - 1: "ORDER_FIRST", - 2: "ANCESTOR_FIRST", - 3: "FILTER_FIRST", -} -var Query_Hint_value = map[string]int32{ - "ORDER_FIRST": 1, - "ANCESTOR_FIRST": 2, - "FILTER_FIRST": 3, -} - -func (x Query_Hint) Enum() *Query_Hint { - p := new(Query_Hint) - *p = x - return p -} -func (x Query_Hint) String() string { - return proto.EnumName(Query_Hint_name, int32(x)) -} -func (x *Query_Hint) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Query_Hint_value, data, "Query_Hint") - if err != nil { - return err - } - *x = Query_Hint(value) - return nil -} -func (Query_Hint) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0} -} - -type Query_Filter_Operator int32 - -const ( - Query_Filter_LESS_THAN Query_Filter_Operator = 1 - Query_Filter_LESS_THAN_OR_EQUAL Query_Filter_Operator = 2 - Query_Filter_GREATER_THAN Query_Filter_Operator = 3 - Query_Filter_GREATER_THAN_OR_EQUAL Query_Filter_Operator = 4 - Query_Filter_EQUAL Query_Filter_Operator = 5 - Query_Filter_IN Query_Filter_Operator = 6 - Query_Filter_EXISTS Query_Filter_Operator = 7 -) - -var Query_Filter_Operator_name = map[int32]string{ - 1: "LESS_THAN", - 2: "LESS_THAN_OR_EQUAL", - 3: "GREATER_THAN", - 4: "GREATER_THAN_OR_EQUAL", - 5: "EQUAL", - 6: "IN", - 7: "EXISTS", -} -var Query_Filter_Operator_value = map[string]int32{ - "LESS_THAN": 1, - "LESS_THAN_OR_EQUAL": 2, - "GREATER_THAN": 3, - "GREATER_THAN_OR_EQUAL": 4, - "EQUAL": 5, - "IN": 6, - "EXISTS": 7, -} - -func (x Query_Filter_Operator) Enum() *Query_Filter_Operator { - p := new(Query_Filter_Operator) - *p = x - return p -} -func (x Query_Filter_Operator) String() string { - return proto.EnumName(Query_Filter_Operator_name, int32(x)) -} -func (x *Query_Filter_Operator) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Query_Filter_Operator_value, data, "Query_Filter_Operator") - if err != nil { - return err - } - *x = Query_Filter_Operator(value) - return nil -} -func (Query_Filter_Operator) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0, 0} -} - -type Query_Order_Direction int32 - -const ( - Query_Order_ASCENDING Query_Order_Direction = 1 - Query_Order_DESCENDING Query_Order_Direction = 2 -) - -var Query_Order_Direction_name = map[int32]string{ - 1: "ASCENDING", - 2: "DESCENDING", -} -var Query_Order_Direction_value = map[string]int32{ - "ASCENDING": 1, - "DESCENDING": 2, -} - -func (x Query_Order_Direction) Enum() *Query_Order_Direction { - p := new(Query_Order_Direction) - *p = x - return p -} -func (x Query_Order_Direction) String() string { - return proto.EnumName(Query_Order_Direction_name, int32(x)) -} -func (x *Query_Order_Direction) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Query_Order_Direction_value, data, "Query_Order_Direction") - if err != nil { - return err - } - *x = Query_Order_Direction(value) - return nil -} -func (Query_Order_Direction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1, 0} -} - -type Error_ErrorCode int32 - -const ( - Error_BAD_REQUEST Error_ErrorCode = 1 - Error_CONCURRENT_TRANSACTION Error_ErrorCode = 2 - Error_INTERNAL_ERROR Error_ErrorCode = 3 - Error_NEED_INDEX Error_ErrorCode = 4 - Error_TIMEOUT Error_ErrorCode = 5 - Error_PERMISSION_DENIED Error_ErrorCode = 6 - Error_BIGTABLE_ERROR Error_ErrorCode = 7 - Error_COMMITTED_BUT_STILL_APPLYING Error_ErrorCode = 8 - Error_CAPABILITY_DISABLED Error_ErrorCode = 9 - Error_TRY_ALTERNATE_BACKEND Error_ErrorCode = 10 - Error_SAFE_TIME_TOO_OLD Error_ErrorCode = 11 -) - -var Error_ErrorCode_name = map[int32]string{ - 1: "BAD_REQUEST", - 2: "CONCURRENT_TRANSACTION", - 3: "INTERNAL_ERROR", - 4: "NEED_INDEX", - 5: "TIMEOUT", - 6: "PERMISSION_DENIED", - 7: "BIGTABLE_ERROR", - 8: "COMMITTED_BUT_STILL_APPLYING", - 9: "CAPABILITY_DISABLED", - 10: "TRY_ALTERNATE_BACKEND", - 11: "SAFE_TIME_TOO_OLD", -} -var Error_ErrorCode_value = map[string]int32{ - "BAD_REQUEST": 1, - "CONCURRENT_TRANSACTION": 2, - "INTERNAL_ERROR": 3, - "NEED_INDEX": 4, - "TIMEOUT": 5, - "PERMISSION_DENIED": 6, - "BIGTABLE_ERROR": 7, - "COMMITTED_BUT_STILL_APPLYING": 8, - "CAPABILITY_DISABLED": 9, - "TRY_ALTERNATE_BACKEND": 10, - "SAFE_TIME_TOO_OLD": 11, -} - -func (x Error_ErrorCode) Enum() *Error_ErrorCode { - p := new(Error_ErrorCode) - *p = x - return p -} -func (x Error_ErrorCode) String() string { - return proto.EnumName(Error_ErrorCode_name, int32(x)) -} -func (x *Error_ErrorCode) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Error_ErrorCode_value, data, "Error_ErrorCode") - if err != nil { - return err - } - *x = Error_ErrorCode(value) - return nil -} -func (Error_ErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19, 0} -} - -type PutRequest_AutoIdPolicy int32 - -const ( - PutRequest_CURRENT PutRequest_AutoIdPolicy = 0 - PutRequest_SEQUENTIAL PutRequest_AutoIdPolicy = 1 -) - -var PutRequest_AutoIdPolicy_name = map[int32]string{ - 0: "CURRENT", - 1: "SEQUENTIAL", -} -var PutRequest_AutoIdPolicy_value = map[string]int32{ - "CURRENT": 0, - "SEQUENTIAL": 1, -} - -func (x PutRequest_AutoIdPolicy) Enum() *PutRequest_AutoIdPolicy { - p := new(PutRequest_AutoIdPolicy) - *p = x - return p -} -func (x PutRequest_AutoIdPolicy) String() string { - return proto.EnumName(PutRequest_AutoIdPolicy_name, int32(x)) -} -func (x *PutRequest_AutoIdPolicy) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(PutRequest_AutoIdPolicy_value, data, "PutRequest_AutoIdPolicy") - if err != nil { - return err - } - *x = PutRequest_AutoIdPolicy(value) - return nil -} -func (PutRequest_AutoIdPolicy) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23, 0} -} - -type BeginTransactionRequest_TransactionMode int32 - -const ( - BeginTransactionRequest_UNKNOWN BeginTransactionRequest_TransactionMode = 0 - BeginTransactionRequest_READ_ONLY BeginTransactionRequest_TransactionMode = 1 - BeginTransactionRequest_READ_WRITE BeginTransactionRequest_TransactionMode = 2 -) - -var BeginTransactionRequest_TransactionMode_name = map[int32]string{ - 0: "UNKNOWN", - 1: "READ_ONLY", - 2: "READ_WRITE", -} -var BeginTransactionRequest_TransactionMode_value = map[string]int32{ - "UNKNOWN": 0, - "READ_ONLY": 1, - "READ_WRITE": 2, -} - -func (x BeginTransactionRequest_TransactionMode) Enum() *BeginTransactionRequest_TransactionMode { - p := new(BeginTransactionRequest_TransactionMode) - *p = x - return p -} -func (x BeginTransactionRequest_TransactionMode) String() string { - return proto.EnumName(BeginTransactionRequest_TransactionMode_name, int32(x)) -} -func (x *BeginTransactionRequest_TransactionMode) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(BeginTransactionRequest_TransactionMode_value, data, "BeginTransactionRequest_TransactionMode") - if err != nil { - return err - } - *x = BeginTransactionRequest_TransactionMode(value) - return nil -} -func (BeginTransactionRequest_TransactionMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36, 0} -} - -type Action struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Action) Reset() { *m = Action{} } -func (m *Action) String() string { return proto.CompactTextString(m) } -func (*Action) ProtoMessage() {} -func (*Action) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{0} -} -func (m *Action) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Action.Unmarshal(m, b) -} -func (m *Action) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Action.Marshal(b, m, deterministic) -} -func (dst *Action) XXX_Merge(src proto.Message) { - xxx_messageInfo_Action.Merge(dst, src) -} -func (m *Action) XXX_Size() int { - return xxx_messageInfo_Action.Size(m) -} -func (m *Action) XXX_DiscardUnknown() { - xxx_messageInfo_Action.DiscardUnknown(m) -} - -var xxx_messageInfo_Action proto.InternalMessageInfo - -type PropertyValue struct { - Int64Value *int64 `protobuf:"varint,1,opt,name=int64Value" json:"int64Value,omitempty"` - BooleanValue *bool `protobuf:"varint,2,opt,name=booleanValue" json:"booleanValue,omitempty"` - StringValue *string `protobuf:"bytes,3,opt,name=stringValue" json:"stringValue,omitempty"` - DoubleValue *float64 `protobuf:"fixed64,4,opt,name=doubleValue" json:"doubleValue,omitempty"` - Pointvalue *PropertyValue_PointValue `protobuf:"group,5,opt,name=PointValue,json=pointvalue" json:"pointvalue,omitempty"` - Uservalue *PropertyValue_UserValue `protobuf:"group,8,opt,name=UserValue,json=uservalue" json:"uservalue,omitempty"` - Referencevalue *PropertyValue_ReferenceValue `protobuf:"group,12,opt,name=ReferenceValue,json=referencevalue" json:"referencevalue,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PropertyValue) Reset() { *m = PropertyValue{} } -func (m *PropertyValue) String() string { return proto.CompactTextString(m) } -func (*PropertyValue) ProtoMessage() {} -func (*PropertyValue) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1} -} -func (m *PropertyValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PropertyValue.Unmarshal(m, b) -} -func (m *PropertyValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PropertyValue.Marshal(b, m, deterministic) -} -func (dst *PropertyValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_PropertyValue.Merge(dst, src) -} -func (m *PropertyValue) XXX_Size() int { - return xxx_messageInfo_PropertyValue.Size(m) -} -func (m *PropertyValue) XXX_DiscardUnknown() { - xxx_messageInfo_PropertyValue.DiscardUnknown(m) -} - -var xxx_messageInfo_PropertyValue proto.InternalMessageInfo - -func (m *PropertyValue) GetInt64Value() int64 { - if m != nil && m.Int64Value != nil { - return *m.Int64Value - } - return 0 -} - -func (m *PropertyValue) GetBooleanValue() bool { - if m != nil && m.BooleanValue != nil { - return *m.BooleanValue - } - return false -} - -func (m *PropertyValue) GetStringValue() string { - if m != nil && m.StringValue != nil { - return *m.StringValue - } - return "" -} - -func (m *PropertyValue) GetDoubleValue() float64 { - if m != nil && m.DoubleValue != nil { - return *m.DoubleValue - } - return 0 -} - -func (m *PropertyValue) GetPointvalue() *PropertyValue_PointValue { - if m != nil { - return m.Pointvalue - } - return nil -} - -func (m *PropertyValue) GetUservalue() *PropertyValue_UserValue { - if m != nil { - return m.Uservalue - } - return nil -} - -func (m *PropertyValue) GetReferencevalue() *PropertyValue_ReferenceValue { - if m != nil { - return m.Referencevalue - } - return nil -} - -type PropertyValue_PointValue struct { - X *float64 `protobuf:"fixed64,6,req,name=x" json:"x,omitempty"` - Y *float64 `protobuf:"fixed64,7,req,name=y" json:"y,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PropertyValue_PointValue) Reset() { *m = PropertyValue_PointValue{} } -func (m *PropertyValue_PointValue) String() string { return proto.CompactTextString(m) } -func (*PropertyValue_PointValue) ProtoMessage() {} -func (*PropertyValue_PointValue) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 0} -} -func (m *PropertyValue_PointValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PropertyValue_PointValue.Unmarshal(m, b) -} -func (m *PropertyValue_PointValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PropertyValue_PointValue.Marshal(b, m, deterministic) -} -func (dst *PropertyValue_PointValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_PropertyValue_PointValue.Merge(dst, src) -} -func (m *PropertyValue_PointValue) XXX_Size() int { - return xxx_messageInfo_PropertyValue_PointValue.Size(m) -} -func (m *PropertyValue_PointValue) XXX_DiscardUnknown() { - xxx_messageInfo_PropertyValue_PointValue.DiscardUnknown(m) -} - -var xxx_messageInfo_PropertyValue_PointValue proto.InternalMessageInfo - -func (m *PropertyValue_PointValue) GetX() float64 { - if m != nil && m.X != nil { - return *m.X - } - return 0 -} - -func (m *PropertyValue_PointValue) GetY() float64 { - if m != nil && m.Y != nil { - return *m.Y - } - return 0 -} - -type PropertyValue_UserValue struct { - Email *string `protobuf:"bytes,9,req,name=email" json:"email,omitempty"` - AuthDomain *string `protobuf:"bytes,10,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"` - Nickname *string `protobuf:"bytes,11,opt,name=nickname" json:"nickname,omitempty"` - FederatedIdentity *string `protobuf:"bytes,21,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"` - FederatedProvider *string `protobuf:"bytes,22,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PropertyValue_UserValue) Reset() { *m = PropertyValue_UserValue{} } -func (m *PropertyValue_UserValue) String() string { return proto.CompactTextString(m) } -func (*PropertyValue_UserValue) ProtoMessage() {} -func (*PropertyValue_UserValue) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 1} -} -func (m *PropertyValue_UserValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PropertyValue_UserValue.Unmarshal(m, b) -} -func (m *PropertyValue_UserValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PropertyValue_UserValue.Marshal(b, m, deterministic) -} -func (dst *PropertyValue_UserValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_PropertyValue_UserValue.Merge(dst, src) -} -func (m *PropertyValue_UserValue) XXX_Size() int { - return xxx_messageInfo_PropertyValue_UserValue.Size(m) -} -func (m *PropertyValue_UserValue) XXX_DiscardUnknown() { - xxx_messageInfo_PropertyValue_UserValue.DiscardUnknown(m) -} - -var xxx_messageInfo_PropertyValue_UserValue proto.InternalMessageInfo - -func (m *PropertyValue_UserValue) GetEmail() string { - if m != nil && m.Email != nil { - return *m.Email - } - return "" -} - -func (m *PropertyValue_UserValue) GetAuthDomain() string { - if m != nil && m.AuthDomain != nil { - return *m.AuthDomain - } - return "" -} - -func (m *PropertyValue_UserValue) GetNickname() string { - if m != nil && m.Nickname != nil { - return *m.Nickname - } - return "" -} - -func (m *PropertyValue_UserValue) GetFederatedIdentity() string { - if m != nil && m.FederatedIdentity != nil { - return *m.FederatedIdentity - } - return "" -} - -func (m *PropertyValue_UserValue) GetFederatedProvider() string { - if m != nil && m.FederatedProvider != nil { - return *m.FederatedProvider - } - return "" -} - -type PropertyValue_ReferenceValue struct { - App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"` - NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` - Pathelement []*PropertyValue_ReferenceValue_PathElement `protobuf:"group,14,rep,name=PathElement,json=pathelement" json:"pathelement,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PropertyValue_ReferenceValue) Reset() { *m = PropertyValue_ReferenceValue{} } -func (m *PropertyValue_ReferenceValue) String() string { return proto.CompactTextString(m) } -func (*PropertyValue_ReferenceValue) ProtoMessage() {} -func (*PropertyValue_ReferenceValue) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2} -} -func (m *PropertyValue_ReferenceValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PropertyValue_ReferenceValue.Unmarshal(m, b) -} -func (m *PropertyValue_ReferenceValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PropertyValue_ReferenceValue.Marshal(b, m, deterministic) -} -func (dst *PropertyValue_ReferenceValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_PropertyValue_ReferenceValue.Merge(dst, src) -} -func (m *PropertyValue_ReferenceValue) XXX_Size() int { - return xxx_messageInfo_PropertyValue_ReferenceValue.Size(m) -} -func (m *PropertyValue_ReferenceValue) XXX_DiscardUnknown() { - xxx_messageInfo_PropertyValue_ReferenceValue.DiscardUnknown(m) -} - -var xxx_messageInfo_PropertyValue_ReferenceValue proto.InternalMessageInfo - -func (m *PropertyValue_ReferenceValue) GetApp() string { - if m != nil && m.App != nil { - return *m.App - } - return "" -} - -func (m *PropertyValue_ReferenceValue) GetNameSpace() string { - if m != nil && m.NameSpace != nil { - return *m.NameSpace - } - return "" -} - -func (m *PropertyValue_ReferenceValue) GetPathelement() []*PropertyValue_ReferenceValue_PathElement { - if m != nil { - return m.Pathelement - } - return nil -} - -type PropertyValue_ReferenceValue_PathElement struct { - Type *string `protobuf:"bytes,15,req,name=type" json:"type,omitempty"` - Id *int64 `protobuf:"varint,16,opt,name=id" json:"id,omitempty"` - Name *string `protobuf:"bytes,17,opt,name=name" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PropertyValue_ReferenceValue_PathElement) Reset() { - *m = PropertyValue_ReferenceValue_PathElement{} -} -func (m *PropertyValue_ReferenceValue_PathElement) String() string { return proto.CompactTextString(m) } -func (*PropertyValue_ReferenceValue_PathElement) ProtoMessage() {} -func (*PropertyValue_ReferenceValue_PathElement) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2, 0} -} -func (m *PropertyValue_ReferenceValue_PathElement) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Unmarshal(m, b) -} -func (m *PropertyValue_ReferenceValue_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Marshal(b, m, deterministic) -} -func (dst *PropertyValue_ReferenceValue_PathElement) XXX_Merge(src proto.Message) { - xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Merge(dst, src) -} -func (m *PropertyValue_ReferenceValue_PathElement) XXX_Size() int { - return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Size(m) -} -func (m *PropertyValue_ReferenceValue_PathElement) XXX_DiscardUnknown() { - xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.DiscardUnknown(m) -} - -var xxx_messageInfo_PropertyValue_ReferenceValue_PathElement proto.InternalMessageInfo - -func (m *PropertyValue_ReferenceValue_PathElement) GetType() string { - if m != nil && m.Type != nil { - return *m.Type - } - return "" -} - -func (m *PropertyValue_ReferenceValue_PathElement) GetId() int64 { - if m != nil && m.Id != nil { - return *m.Id - } - return 0 -} - -func (m *PropertyValue_ReferenceValue_PathElement) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -type Property struct { - Meaning *Property_Meaning `protobuf:"varint,1,opt,name=meaning,enum=appengine.Property_Meaning,def=0" json:"meaning,omitempty"` - MeaningUri *string `protobuf:"bytes,2,opt,name=meaning_uri,json=meaningUri" json:"meaning_uri,omitempty"` - Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"` - Value *PropertyValue `protobuf:"bytes,5,req,name=value" json:"value,omitempty"` - Multiple *bool `protobuf:"varint,4,req,name=multiple" json:"multiple,omitempty"` - Searchable *bool `protobuf:"varint,6,opt,name=searchable,def=0" json:"searchable,omitempty"` - FtsTokenizationOption *Property_FtsTokenizationOption `protobuf:"varint,8,opt,name=fts_tokenization_option,json=ftsTokenizationOption,enum=appengine.Property_FtsTokenizationOption" json:"fts_tokenization_option,omitempty"` - Locale *string `protobuf:"bytes,9,opt,name=locale,def=en" json:"locale,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Property) Reset() { *m = Property{} } -func (m *Property) String() string { return proto.CompactTextString(m) } -func (*Property) ProtoMessage() {} -func (*Property) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2} -} -func (m *Property) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Property.Unmarshal(m, b) -} -func (m *Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Property.Marshal(b, m, deterministic) -} -func (dst *Property) XXX_Merge(src proto.Message) { - xxx_messageInfo_Property.Merge(dst, src) -} -func (m *Property) XXX_Size() int { - return xxx_messageInfo_Property.Size(m) -} -func (m *Property) XXX_DiscardUnknown() { - xxx_messageInfo_Property.DiscardUnknown(m) -} - -var xxx_messageInfo_Property proto.InternalMessageInfo - -const Default_Property_Meaning Property_Meaning = Property_NO_MEANING -const Default_Property_Searchable bool = false -const Default_Property_Locale string = "en" - -func (m *Property) GetMeaning() Property_Meaning { - if m != nil && m.Meaning != nil { - return *m.Meaning - } - return Default_Property_Meaning -} - -func (m *Property) GetMeaningUri() string { - if m != nil && m.MeaningUri != nil { - return *m.MeaningUri - } - return "" -} - -func (m *Property) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -func (m *Property) GetValue() *PropertyValue { - if m != nil { - return m.Value - } - return nil -} - -func (m *Property) GetMultiple() bool { - if m != nil && m.Multiple != nil { - return *m.Multiple - } - return false -} - -func (m *Property) GetSearchable() bool { - if m != nil && m.Searchable != nil { - return *m.Searchable - } - return Default_Property_Searchable -} - -func (m *Property) GetFtsTokenizationOption() Property_FtsTokenizationOption { - if m != nil && m.FtsTokenizationOption != nil { - return *m.FtsTokenizationOption - } - return Property_HTML -} - -func (m *Property) GetLocale() string { - if m != nil && m.Locale != nil { - return *m.Locale - } - return Default_Property_Locale -} - -type Path struct { - Element []*Path_Element `protobuf:"group,1,rep,name=Element,json=element" json:"element,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Path) Reset() { *m = Path{} } -func (m *Path) String() string { return proto.CompactTextString(m) } -func (*Path) ProtoMessage() {} -func (*Path) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3} -} -func (m *Path) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Path.Unmarshal(m, b) -} -func (m *Path) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Path.Marshal(b, m, deterministic) -} -func (dst *Path) XXX_Merge(src proto.Message) { - xxx_messageInfo_Path.Merge(dst, src) -} -func (m *Path) XXX_Size() int { - return xxx_messageInfo_Path.Size(m) -} -func (m *Path) XXX_DiscardUnknown() { - xxx_messageInfo_Path.DiscardUnknown(m) -} - -var xxx_messageInfo_Path proto.InternalMessageInfo - -func (m *Path) GetElement() []*Path_Element { - if m != nil { - return m.Element - } - return nil -} - -type Path_Element struct { - Type *string `protobuf:"bytes,2,req,name=type" json:"type,omitempty"` - Id *int64 `protobuf:"varint,3,opt,name=id" json:"id,omitempty"` - Name *string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Path_Element) Reset() { *m = Path_Element{} } -func (m *Path_Element) String() string { return proto.CompactTextString(m) } -func (*Path_Element) ProtoMessage() {} -func (*Path_Element) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3, 0} -} -func (m *Path_Element) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Path_Element.Unmarshal(m, b) -} -func (m *Path_Element) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Path_Element.Marshal(b, m, deterministic) -} -func (dst *Path_Element) XXX_Merge(src proto.Message) { - xxx_messageInfo_Path_Element.Merge(dst, src) -} -func (m *Path_Element) XXX_Size() int { - return xxx_messageInfo_Path_Element.Size(m) -} -func (m *Path_Element) XXX_DiscardUnknown() { - xxx_messageInfo_Path_Element.DiscardUnknown(m) -} - -var xxx_messageInfo_Path_Element proto.InternalMessageInfo - -func (m *Path_Element) GetType() string { - if m != nil && m.Type != nil { - return *m.Type - } - return "" -} - -func (m *Path_Element) GetId() int64 { - if m != nil && m.Id != nil { - return *m.Id - } - return 0 -} - -func (m *Path_Element) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -type Reference struct { - App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"` - NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` - Path *Path `protobuf:"bytes,14,req,name=path" json:"path,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Reference) Reset() { *m = Reference{} } -func (m *Reference) String() string { return proto.CompactTextString(m) } -func (*Reference) ProtoMessage() {} -func (*Reference) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{4} -} -func (m *Reference) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Reference.Unmarshal(m, b) -} -func (m *Reference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Reference.Marshal(b, m, deterministic) -} -func (dst *Reference) XXX_Merge(src proto.Message) { - xxx_messageInfo_Reference.Merge(dst, src) -} -func (m *Reference) XXX_Size() int { - return xxx_messageInfo_Reference.Size(m) -} -func (m *Reference) XXX_DiscardUnknown() { - xxx_messageInfo_Reference.DiscardUnknown(m) -} - -var xxx_messageInfo_Reference proto.InternalMessageInfo - -func (m *Reference) GetApp() string { - if m != nil && m.App != nil { - return *m.App - } - return "" -} - -func (m *Reference) GetNameSpace() string { - if m != nil && m.NameSpace != nil { - return *m.NameSpace - } - return "" -} - -func (m *Reference) GetPath() *Path { - if m != nil { - return m.Path - } - return nil -} - -type User struct { - Email *string `protobuf:"bytes,1,req,name=email" json:"email,omitempty"` - AuthDomain *string `protobuf:"bytes,2,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"` - Nickname *string `protobuf:"bytes,3,opt,name=nickname" json:"nickname,omitempty"` - FederatedIdentity *string `protobuf:"bytes,6,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"` - FederatedProvider *string `protobuf:"bytes,7,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *User) Reset() { *m = User{} } -func (m *User) String() string { return proto.CompactTextString(m) } -func (*User) ProtoMessage() {} -func (*User) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{5} -} -func (m *User) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_User.Unmarshal(m, b) -} -func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_User.Marshal(b, m, deterministic) -} -func (dst *User) XXX_Merge(src proto.Message) { - xxx_messageInfo_User.Merge(dst, src) -} -func (m *User) XXX_Size() int { - return xxx_messageInfo_User.Size(m) -} -func (m *User) XXX_DiscardUnknown() { - xxx_messageInfo_User.DiscardUnknown(m) -} - -var xxx_messageInfo_User proto.InternalMessageInfo - -func (m *User) GetEmail() string { - if m != nil && m.Email != nil { - return *m.Email - } - return "" -} - -func (m *User) GetAuthDomain() string { - if m != nil && m.AuthDomain != nil { - return *m.AuthDomain - } - return "" -} - -func (m *User) GetNickname() string { - if m != nil && m.Nickname != nil { - return *m.Nickname - } - return "" -} - -func (m *User) GetFederatedIdentity() string { - if m != nil && m.FederatedIdentity != nil { - return *m.FederatedIdentity - } - return "" -} - -func (m *User) GetFederatedProvider() string { - if m != nil && m.FederatedProvider != nil { - return *m.FederatedProvider - } - return "" -} - -type EntityProto struct { - Key *Reference `protobuf:"bytes,13,req,name=key" json:"key,omitempty"` - EntityGroup *Path `protobuf:"bytes,16,req,name=entity_group,json=entityGroup" json:"entity_group,omitempty"` - Owner *User `protobuf:"bytes,17,opt,name=owner" json:"owner,omitempty"` - Kind *EntityProto_Kind `protobuf:"varint,4,opt,name=kind,enum=appengine.EntityProto_Kind" json:"kind,omitempty"` - KindUri *string `protobuf:"bytes,5,opt,name=kind_uri,json=kindUri" json:"kind_uri,omitempty"` - Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"` - RawProperty []*Property `protobuf:"bytes,15,rep,name=raw_property,json=rawProperty" json:"raw_property,omitempty"` - Rank *int32 `protobuf:"varint,18,opt,name=rank" json:"rank,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EntityProto) Reset() { *m = EntityProto{} } -func (m *EntityProto) String() string { return proto.CompactTextString(m) } -func (*EntityProto) ProtoMessage() {} -func (*EntityProto) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6} -} -func (m *EntityProto) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntityProto.Unmarshal(m, b) -} -func (m *EntityProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntityProto.Marshal(b, m, deterministic) -} -func (dst *EntityProto) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntityProto.Merge(dst, src) -} -func (m *EntityProto) XXX_Size() int { - return xxx_messageInfo_EntityProto.Size(m) -} -func (m *EntityProto) XXX_DiscardUnknown() { - xxx_messageInfo_EntityProto.DiscardUnknown(m) -} - -var xxx_messageInfo_EntityProto proto.InternalMessageInfo - -func (m *EntityProto) GetKey() *Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *EntityProto) GetEntityGroup() *Path { - if m != nil { - return m.EntityGroup - } - return nil -} - -func (m *EntityProto) GetOwner() *User { - if m != nil { - return m.Owner - } - return nil -} - -func (m *EntityProto) GetKind() EntityProto_Kind { - if m != nil && m.Kind != nil { - return *m.Kind - } - return EntityProto_GD_CONTACT -} - -func (m *EntityProto) GetKindUri() string { - if m != nil && m.KindUri != nil { - return *m.KindUri - } - return "" -} - -func (m *EntityProto) GetProperty() []*Property { - if m != nil { - return m.Property - } - return nil -} - -func (m *EntityProto) GetRawProperty() []*Property { - if m != nil { - return m.RawProperty - } - return nil -} - -func (m *EntityProto) GetRank() int32 { - if m != nil && m.Rank != nil { - return *m.Rank - } - return 0 -} - -type CompositeProperty struct { - IndexId *int64 `protobuf:"varint,1,req,name=index_id,json=indexId" json:"index_id,omitempty"` - Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompositeProperty) Reset() { *m = CompositeProperty{} } -func (m *CompositeProperty) String() string { return proto.CompactTextString(m) } -func (*CompositeProperty) ProtoMessage() {} -func (*CompositeProperty) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{7} -} -func (m *CompositeProperty) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompositeProperty.Unmarshal(m, b) -} -func (m *CompositeProperty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompositeProperty.Marshal(b, m, deterministic) -} -func (dst *CompositeProperty) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompositeProperty.Merge(dst, src) -} -func (m *CompositeProperty) XXX_Size() int { - return xxx_messageInfo_CompositeProperty.Size(m) -} -func (m *CompositeProperty) XXX_DiscardUnknown() { - xxx_messageInfo_CompositeProperty.DiscardUnknown(m) -} - -var xxx_messageInfo_CompositeProperty proto.InternalMessageInfo - -func (m *CompositeProperty) GetIndexId() int64 { - if m != nil && m.IndexId != nil { - return *m.IndexId - } - return 0 -} - -func (m *CompositeProperty) GetValue() []string { - if m != nil { - return m.Value - } - return nil -} - -type Index struct { - EntityType *string `protobuf:"bytes,1,req,name=entity_type,json=entityType" json:"entity_type,omitempty"` - Ancestor *bool `protobuf:"varint,5,req,name=ancestor" json:"ancestor,omitempty"` - Property []*Index_Property `protobuf:"group,2,rep,name=Property,json=property" json:"property,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Index) Reset() { *m = Index{} } -func (m *Index) String() string { return proto.CompactTextString(m) } -func (*Index) ProtoMessage() {} -func (*Index) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8} -} -func (m *Index) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Index.Unmarshal(m, b) -} -func (m *Index) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Index.Marshal(b, m, deterministic) -} -func (dst *Index) XXX_Merge(src proto.Message) { - xxx_messageInfo_Index.Merge(dst, src) -} -func (m *Index) XXX_Size() int { - return xxx_messageInfo_Index.Size(m) -} -func (m *Index) XXX_DiscardUnknown() { - xxx_messageInfo_Index.DiscardUnknown(m) -} - -var xxx_messageInfo_Index proto.InternalMessageInfo - -func (m *Index) GetEntityType() string { - if m != nil && m.EntityType != nil { - return *m.EntityType - } - return "" -} - -func (m *Index) GetAncestor() bool { - if m != nil && m.Ancestor != nil { - return *m.Ancestor - } - return false -} - -func (m *Index) GetProperty() []*Index_Property { - if m != nil { - return m.Property - } - return nil -} - -type Index_Property struct { - Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"` - Direction *Index_Property_Direction `protobuf:"varint,4,opt,name=direction,enum=appengine.Index_Property_Direction,def=1" json:"direction,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Index_Property) Reset() { *m = Index_Property{} } -func (m *Index_Property) String() string { return proto.CompactTextString(m) } -func (*Index_Property) ProtoMessage() {} -func (*Index_Property) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0} -} -func (m *Index_Property) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Index_Property.Unmarshal(m, b) -} -func (m *Index_Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Index_Property.Marshal(b, m, deterministic) -} -func (dst *Index_Property) XXX_Merge(src proto.Message) { - xxx_messageInfo_Index_Property.Merge(dst, src) -} -func (m *Index_Property) XXX_Size() int { - return xxx_messageInfo_Index_Property.Size(m) -} -func (m *Index_Property) XXX_DiscardUnknown() { - xxx_messageInfo_Index_Property.DiscardUnknown(m) -} - -var xxx_messageInfo_Index_Property proto.InternalMessageInfo - -const Default_Index_Property_Direction Index_Property_Direction = Index_Property_ASCENDING - -func (m *Index_Property) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -func (m *Index_Property) GetDirection() Index_Property_Direction { - if m != nil && m.Direction != nil { - return *m.Direction - } - return Default_Index_Property_Direction -} - -type CompositeIndex struct { - AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` - Id *int64 `protobuf:"varint,2,req,name=id" json:"id,omitempty"` - Definition *Index `protobuf:"bytes,3,req,name=definition" json:"definition,omitempty"` - State *CompositeIndex_State `protobuf:"varint,4,req,name=state,enum=appengine.CompositeIndex_State" json:"state,omitempty"` - OnlyUseIfRequired *bool `protobuf:"varint,6,opt,name=only_use_if_required,json=onlyUseIfRequired,def=0" json:"only_use_if_required,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompositeIndex) Reset() { *m = CompositeIndex{} } -func (m *CompositeIndex) String() string { return proto.CompactTextString(m) } -func (*CompositeIndex) ProtoMessage() {} -func (*CompositeIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9} -} -func (m *CompositeIndex) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompositeIndex.Unmarshal(m, b) -} -func (m *CompositeIndex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompositeIndex.Marshal(b, m, deterministic) -} -func (dst *CompositeIndex) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompositeIndex.Merge(dst, src) -} -func (m *CompositeIndex) XXX_Size() int { - return xxx_messageInfo_CompositeIndex.Size(m) -} -func (m *CompositeIndex) XXX_DiscardUnknown() { - xxx_messageInfo_CompositeIndex.DiscardUnknown(m) -} - -var xxx_messageInfo_CompositeIndex proto.InternalMessageInfo - -const Default_CompositeIndex_OnlyUseIfRequired bool = false - -func (m *CompositeIndex) GetAppId() string { - if m != nil && m.AppId != nil { - return *m.AppId - } - return "" -} - -func (m *CompositeIndex) GetId() int64 { - if m != nil && m.Id != nil { - return *m.Id - } - return 0 -} - -func (m *CompositeIndex) GetDefinition() *Index { - if m != nil { - return m.Definition - } - return nil -} - -func (m *CompositeIndex) GetState() CompositeIndex_State { - if m != nil && m.State != nil { - return *m.State - } - return CompositeIndex_WRITE_ONLY -} - -func (m *CompositeIndex) GetOnlyUseIfRequired() bool { - if m != nil && m.OnlyUseIfRequired != nil { - return *m.OnlyUseIfRequired - } - return Default_CompositeIndex_OnlyUseIfRequired -} - -type IndexPostfix struct { - IndexValue []*IndexPostfix_IndexValue `protobuf:"bytes,1,rep,name=index_value,json=indexValue" json:"index_value,omitempty"` - Key *Reference `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` - Before *bool `protobuf:"varint,3,opt,name=before,def=1" json:"before,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *IndexPostfix) Reset() { *m = IndexPostfix{} } -func (m *IndexPostfix) String() string { return proto.CompactTextString(m) } -func (*IndexPostfix) ProtoMessage() {} -func (*IndexPostfix) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10} -} -func (m *IndexPostfix) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_IndexPostfix.Unmarshal(m, b) -} -func (m *IndexPostfix) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_IndexPostfix.Marshal(b, m, deterministic) -} -func (dst *IndexPostfix) XXX_Merge(src proto.Message) { - xxx_messageInfo_IndexPostfix.Merge(dst, src) -} -func (m *IndexPostfix) XXX_Size() int { - return xxx_messageInfo_IndexPostfix.Size(m) -} -func (m *IndexPostfix) XXX_DiscardUnknown() { - xxx_messageInfo_IndexPostfix.DiscardUnknown(m) -} - -var xxx_messageInfo_IndexPostfix proto.InternalMessageInfo - -const Default_IndexPostfix_Before bool = true - -func (m *IndexPostfix) GetIndexValue() []*IndexPostfix_IndexValue { - if m != nil { - return m.IndexValue - } - return nil -} - -func (m *IndexPostfix) GetKey() *Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *IndexPostfix) GetBefore() bool { - if m != nil && m.Before != nil { - return *m.Before - } - return Default_IndexPostfix_Before -} - -type IndexPostfix_IndexValue struct { - PropertyName *string `protobuf:"bytes,1,req,name=property_name,json=propertyName" json:"property_name,omitempty"` - Value *PropertyValue `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *IndexPostfix_IndexValue) Reset() { *m = IndexPostfix_IndexValue{} } -func (m *IndexPostfix_IndexValue) String() string { return proto.CompactTextString(m) } -func (*IndexPostfix_IndexValue) ProtoMessage() {} -func (*IndexPostfix_IndexValue) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10, 0} -} -func (m *IndexPostfix_IndexValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_IndexPostfix_IndexValue.Unmarshal(m, b) -} -func (m *IndexPostfix_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_IndexPostfix_IndexValue.Marshal(b, m, deterministic) -} -func (dst *IndexPostfix_IndexValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_IndexPostfix_IndexValue.Merge(dst, src) -} -func (m *IndexPostfix_IndexValue) XXX_Size() int { - return xxx_messageInfo_IndexPostfix_IndexValue.Size(m) -} -func (m *IndexPostfix_IndexValue) XXX_DiscardUnknown() { - xxx_messageInfo_IndexPostfix_IndexValue.DiscardUnknown(m) -} - -var xxx_messageInfo_IndexPostfix_IndexValue proto.InternalMessageInfo - -func (m *IndexPostfix_IndexValue) GetPropertyName() string { - if m != nil && m.PropertyName != nil { - return *m.PropertyName - } - return "" -} - -func (m *IndexPostfix_IndexValue) GetValue() *PropertyValue { - if m != nil { - return m.Value - } - return nil -} - -type IndexPosition struct { - Key *string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` - Before *bool `protobuf:"varint,2,opt,name=before,def=1" json:"before,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *IndexPosition) Reset() { *m = IndexPosition{} } -func (m *IndexPosition) String() string { return proto.CompactTextString(m) } -func (*IndexPosition) ProtoMessage() {} -func (*IndexPosition) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{11} -} -func (m *IndexPosition) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_IndexPosition.Unmarshal(m, b) -} -func (m *IndexPosition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_IndexPosition.Marshal(b, m, deterministic) -} -func (dst *IndexPosition) XXX_Merge(src proto.Message) { - xxx_messageInfo_IndexPosition.Merge(dst, src) -} -func (m *IndexPosition) XXX_Size() int { - return xxx_messageInfo_IndexPosition.Size(m) -} -func (m *IndexPosition) XXX_DiscardUnknown() { - xxx_messageInfo_IndexPosition.DiscardUnknown(m) -} - -var xxx_messageInfo_IndexPosition proto.InternalMessageInfo - -const Default_IndexPosition_Before bool = true - -func (m *IndexPosition) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *IndexPosition) GetBefore() bool { - if m != nil && m.Before != nil { - return *m.Before - } - return Default_IndexPosition_Before -} - -type Snapshot struct { - Ts *int64 `protobuf:"varint,1,req,name=ts" json:"ts,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Snapshot) Reset() { *m = Snapshot{} } -func (m *Snapshot) String() string { return proto.CompactTextString(m) } -func (*Snapshot) ProtoMessage() {} -func (*Snapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12} -} -func (m *Snapshot) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Snapshot.Unmarshal(m, b) -} -func (m *Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Snapshot.Marshal(b, m, deterministic) -} -func (dst *Snapshot) XXX_Merge(src proto.Message) { - xxx_messageInfo_Snapshot.Merge(dst, src) -} -func (m *Snapshot) XXX_Size() int { - return xxx_messageInfo_Snapshot.Size(m) -} -func (m *Snapshot) XXX_DiscardUnknown() { - xxx_messageInfo_Snapshot.DiscardUnknown(m) -} - -var xxx_messageInfo_Snapshot proto.InternalMessageInfo - -func (m *Snapshot) GetTs() int64 { - if m != nil && m.Ts != nil { - return *m.Ts - } - return 0 -} - -type InternalHeader struct { - Qos *string `protobuf:"bytes,1,opt,name=qos" json:"qos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *InternalHeader) Reset() { *m = InternalHeader{} } -func (m *InternalHeader) String() string { return proto.CompactTextString(m) } -func (*InternalHeader) ProtoMessage() {} -func (*InternalHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{13} -} -func (m *InternalHeader) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_InternalHeader.Unmarshal(m, b) -} -func (m *InternalHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_InternalHeader.Marshal(b, m, deterministic) -} -func (dst *InternalHeader) XXX_Merge(src proto.Message) { - xxx_messageInfo_InternalHeader.Merge(dst, src) -} -func (m *InternalHeader) XXX_Size() int { - return xxx_messageInfo_InternalHeader.Size(m) -} -func (m *InternalHeader) XXX_DiscardUnknown() { - xxx_messageInfo_InternalHeader.DiscardUnknown(m) -} - -var xxx_messageInfo_InternalHeader proto.InternalMessageInfo - -func (m *InternalHeader) GetQos() string { - if m != nil && m.Qos != nil { - return *m.Qos - } - return "" -} - -type Transaction struct { - Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"` - Handle *uint64 `protobuf:"fixed64,1,req,name=handle" json:"handle,omitempty"` - App *string `protobuf:"bytes,2,req,name=app" json:"app,omitempty"` - MarkChanges *bool `protobuf:"varint,3,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Transaction) Reset() { *m = Transaction{} } -func (m *Transaction) String() string { return proto.CompactTextString(m) } -func (*Transaction) ProtoMessage() {} -func (*Transaction) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{14} -} -func (m *Transaction) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Transaction.Unmarshal(m, b) -} -func (m *Transaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Transaction.Marshal(b, m, deterministic) -} -func (dst *Transaction) XXX_Merge(src proto.Message) { - xxx_messageInfo_Transaction.Merge(dst, src) -} -func (m *Transaction) XXX_Size() int { - return xxx_messageInfo_Transaction.Size(m) -} -func (m *Transaction) XXX_DiscardUnknown() { - xxx_messageInfo_Transaction.DiscardUnknown(m) -} - -var xxx_messageInfo_Transaction proto.InternalMessageInfo - -const Default_Transaction_MarkChanges bool = false - -func (m *Transaction) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *Transaction) GetHandle() uint64 { - if m != nil && m.Handle != nil { - return *m.Handle - } - return 0 -} - -func (m *Transaction) GetApp() string { - if m != nil && m.App != nil { - return *m.App - } - return "" -} - -func (m *Transaction) GetMarkChanges() bool { - if m != nil && m.MarkChanges != nil { - return *m.MarkChanges - } - return Default_Transaction_MarkChanges -} - -type Query struct { - Header *InternalHeader `protobuf:"bytes,39,opt,name=header" json:"header,omitempty"` - App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"` - NameSpace *string `protobuf:"bytes,29,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` - Kind *string `protobuf:"bytes,3,opt,name=kind" json:"kind,omitempty"` - Ancestor *Reference `protobuf:"bytes,17,opt,name=ancestor" json:"ancestor,omitempty"` - Filter []*Query_Filter `protobuf:"group,4,rep,name=Filter,json=filter" json:"filter,omitempty"` - SearchQuery *string `protobuf:"bytes,8,opt,name=search_query,json=searchQuery" json:"search_query,omitempty"` - Order []*Query_Order `protobuf:"group,9,rep,name=Order,json=order" json:"order,omitempty"` - Hint *Query_Hint `protobuf:"varint,18,opt,name=hint,enum=appengine.Query_Hint" json:"hint,omitempty"` - Count *int32 `protobuf:"varint,23,opt,name=count" json:"count,omitempty"` - Offset *int32 `protobuf:"varint,12,opt,name=offset,def=0" json:"offset,omitempty"` - Limit *int32 `protobuf:"varint,16,opt,name=limit" json:"limit,omitempty"` - CompiledCursor *CompiledCursor `protobuf:"bytes,30,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"` - EndCompiledCursor *CompiledCursor `protobuf:"bytes,31,opt,name=end_compiled_cursor,json=endCompiledCursor" json:"end_compiled_cursor,omitempty"` - CompositeIndex []*CompositeIndex `protobuf:"bytes,19,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"` - RequirePerfectPlan *bool `protobuf:"varint,20,opt,name=require_perfect_plan,json=requirePerfectPlan,def=0" json:"require_perfect_plan,omitempty"` - KeysOnly *bool `protobuf:"varint,21,opt,name=keys_only,json=keysOnly,def=0" json:"keys_only,omitempty"` - Transaction *Transaction `protobuf:"bytes,22,opt,name=transaction" json:"transaction,omitempty"` - Compile *bool `protobuf:"varint,25,opt,name=compile,def=0" json:"compile,omitempty"` - FailoverMs *int64 `protobuf:"varint,26,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"` - Strong *bool `protobuf:"varint,32,opt,name=strong" json:"strong,omitempty"` - PropertyName []string `protobuf:"bytes,33,rep,name=property_name,json=propertyName" json:"property_name,omitempty"` - GroupByPropertyName []string `protobuf:"bytes,34,rep,name=group_by_property_name,json=groupByPropertyName" json:"group_by_property_name,omitempty"` - Distinct *bool `protobuf:"varint,24,opt,name=distinct" json:"distinct,omitempty"` - MinSafeTimeSeconds *int64 `protobuf:"varint,35,opt,name=min_safe_time_seconds,json=minSafeTimeSeconds" json:"min_safe_time_seconds,omitempty"` - SafeReplicaName []string `protobuf:"bytes,36,rep,name=safe_replica_name,json=safeReplicaName" json:"safe_replica_name,omitempty"` - PersistOffset *bool `protobuf:"varint,37,opt,name=persist_offset,json=persistOffset,def=0" json:"persist_offset,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Query) Reset() { *m = Query{} } -func (m *Query) String() string { return proto.CompactTextString(m) } -func (*Query) ProtoMessage() {} -func (*Query) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15} -} -func (m *Query) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Query.Unmarshal(m, b) -} -func (m *Query) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Query.Marshal(b, m, deterministic) -} -func (dst *Query) XXX_Merge(src proto.Message) { - xxx_messageInfo_Query.Merge(dst, src) -} -func (m *Query) XXX_Size() int { - return xxx_messageInfo_Query.Size(m) -} -func (m *Query) XXX_DiscardUnknown() { - xxx_messageInfo_Query.DiscardUnknown(m) -} - -var xxx_messageInfo_Query proto.InternalMessageInfo - -const Default_Query_Offset int32 = 0 -const Default_Query_RequirePerfectPlan bool = false -const Default_Query_KeysOnly bool = false -const Default_Query_Compile bool = false -const Default_Query_PersistOffset bool = false - -func (m *Query) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *Query) GetApp() string { - if m != nil && m.App != nil { - return *m.App - } - return "" -} - -func (m *Query) GetNameSpace() string { - if m != nil && m.NameSpace != nil { - return *m.NameSpace - } - return "" -} - -func (m *Query) GetKind() string { - if m != nil && m.Kind != nil { - return *m.Kind - } - return "" -} - -func (m *Query) GetAncestor() *Reference { - if m != nil { - return m.Ancestor - } - return nil -} - -func (m *Query) GetFilter() []*Query_Filter { - if m != nil { - return m.Filter - } - return nil -} - -func (m *Query) GetSearchQuery() string { - if m != nil && m.SearchQuery != nil { - return *m.SearchQuery - } - return "" -} - -func (m *Query) GetOrder() []*Query_Order { - if m != nil { - return m.Order - } - return nil -} - -func (m *Query) GetHint() Query_Hint { - if m != nil && m.Hint != nil { - return *m.Hint - } - return Query_ORDER_FIRST -} - -func (m *Query) GetCount() int32 { - if m != nil && m.Count != nil { - return *m.Count - } - return 0 -} - -func (m *Query) GetOffset() int32 { - if m != nil && m.Offset != nil { - return *m.Offset - } - return Default_Query_Offset -} - -func (m *Query) GetLimit() int32 { - if m != nil && m.Limit != nil { - return *m.Limit - } - return 0 -} - -func (m *Query) GetCompiledCursor() *CompiledCursor { - if m != nil { - return m.CompiledCursor - } - return nil -} - -func (m *Query) GetEndCompiledCursor() *CompiledCursor { - if m != nil { - return m.EndCompiledCursor - } - return nil -} - -func (m *Query) GetCompositeIndex() []*CompositeIndex { - if m != nil { - return m.CompositeIndex - } - return nil -} - -func (m *Query) GetRequirePerfectPlan() bool { - if m != nil && m.RequirePerfectPlan != nil { - return *m.RequirePerfectPlan - } - return Default_Query_RequirePerfectPlan -} - -func (m *Query) GetKeysOnly() bool { - if m != nil && m.KeysOnly != nil { - return *m.KeysOnly - } - return Default_Query_KeysOnly -} - -func (m *Query) GetTransaction() *Transaction { - if m != nil { - return m.Transaction - } - return nil -} - -func (m *Query) GetCompile() bool { - if m != nil && m.Compile != nil { - return *m.Compile - } - return Default_Query_Compile -} - -func (m *Query) GetFailoverMs() int64 { - if m != nil && m.FailoverMs != nil { - return *m.FailoverMs - } - return 0 -} - -func (m *Query) GetStrong() bool { - if m != nil && m.Strong != nil { - return *m.Strong - } - return false -} - -func (m *Query) GetPropertyName() []string { - if m != nil { - return m.PropertyName - } - return nil -} - -func (m *Query) GetGroupByPropertyName() []string { - if m != nil { - return m.GroupByPropertyName - } - return nil -} - -func (m *Query) GetDistinct() bool { - if m != nil && m.Distinct != nil { - return *m.Distinct - } - return false -} - -func (m *Query) GetMinSafeTimeSeconds() int64 { - if m != nil && m.MinSafeTimeSeconds != nil { - return *m.MinSafeTimeSeconds - } - return 0 -} - -func (m *Query) GetSafeReplicaName() []string { - if m != nil { - return m.SafeReplicaName - } - return nil -} - -func (m *Query) GetPersistOffset() bool { - if m != nil && m.PersistOffset != nil { - return *m.PersistOffset - } - return Default_Query_PersistOffset -} - -type Query_Filter struct { - Op *Query_Filter_Operator `protobuf:"varint,6,req,name=op,enum=appengine.Query_Filter_Operator" json:"op,omitempty"` - Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Query_Filter) Reset() { *m = Query_Filter{} } -func (m *Query_Filter) String() string { return proto.CompactTextString(m) } -func (*Query_Filter) ProtoMessage() {} -func (*Query_Filter) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0} -} -func (m *Query_Filter) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Query_Filter.Unmarshal(m, b) -} -func (m *Query_Filter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Query_Filter.Marshal(b, m, deterministic) -} -func (dst *Query_Filter) XXX_Merge(src proto.Message) { - xxx_messageInfo_Query_Filter.Merge(dst, src) -} -func (m *Query_Filter) XXX_Size() int { - return xxx_messageInfo_Query_Filter.Size(m) -} -func (m *Query_Filter) XXX_DiscardUnknown() { - xxx_messageInfo_Query_Filter.DiscardUnknown(m) -} - -var xxx_messageInfo_Query_Filter proto.InternalMessageInfo - -func (m *Query_Filter) GetOp() Query_Filter_Operator { - if m != nil && m.Op != nil { - return *m.Op - } - return Query_Filter_LESS_THAN -} - -func (m *Query_Filter) GetProperty() []*Property { - if m != nil { - return m.Property - } - return nil -} - -type Query_Order struct { - Property *string `protobuf:"bytes,10,req,name=property" json:"property,omitempty"` - Direction *Query_Order_Direction `protobuf:"varint,11,opt,name=direction,enum=appengine.Query_Order_Direction,def=1" json:"direction,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Query_Order) Reset() { *m = Query_Order{} } -func (m *Query_Order) String() string { return proto.CompactTextString(m) } -func (*Query_Order) ProtoMessage() {} -func (*Query_Order) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1} -} -func (m *Query_Order) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Query_Order.Unmarshal(m, b) -} -func (m *Query_Order) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Query_Order.Marshal(b, m, deterministic) -} -func (dst *Query_Order) XXX_Merge(src proto.Message) { - xxx_messageInfo_Query_Order.Merge(dst, src) -} -func (m *Query_Order) XXX_Size() int { - return xxx_messageInfo_Query_Order.Size(m) -} -func (m *Query_Order) XXX_DiscardUnknown() { - xxx_messageInfo_Query_Order.DiscardUnknown(m) -} - -var xxx_messageInfo_Query_Order proto.InternalMessageInfo - -const Default_Query_Order_Direction Query_Order_Direction = Query_Order_ASCENDING - -func (m *Query_Order) GetProperty() string { - if m != nil && m.Property != nil { - return *m.Property - } - return "" -} - -func (m *Query_Order) GetDirection() Query_Order_Direction { - if m != nil && m.Direction != nil { - return *m.Direction - } - return Default_Query_Order_Direction -} - -type CompiledQuery struct { - Primaryscan *CompiledQuery_PrimaryScan `protobuf:"group,1,req,name=PrimaryScan,json=primaryscan" json:"primaryscan,omitempty"` - Mergejoinscan []*CompiledQuery_MergeJoinScan `protobuf:"group,7,rep,name=MergeJoinScan,json=mergejoinscan" json:"mergejoinscan,omitempty"` - IndexDef *Index `protobuf:"bytes,21,opt,name=index_def,json=indexDef" json:"index_def,omitempty"` - Offset *int32 `protobuf:"varint,10,opt,name=offset,def=0" json:"offset,omitempty"` - Limit *int32 `protobuf:"varint,11,opt,name=limit" json:"limit,omitempty"` - KeysOnly *bool `protobuf:"varint,12,req,name=keys_only,json=keysOnly" json:"keys_only,omitempty"` - PropertyName []string `protobuf:"bytes,24,rep,name=property_name,json=propertyName" json:"property_name,omitempty"` - DistinctInfixSize *int32 `protobuf:"varint,25,opt,name=distinct_infix_size,json=distinctInfixSize" json:"distinct_infix_size,omitempty"` - Entityfilter *CompiledQuery_EntityFilter `protobuf:"group,13,opt,name=EntityFilter,json=entityfilter" json:"entityfilter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledQuery) Reset() { *m = CompiledQuery{} } -func (m *CompiledQuery) String() string { return proto.CompactTextString(m) } -func (*CompiledQuery) ProtoMessage() {} -func (*CompiledQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16} -} -func (m *CompiledQuery) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledQuery.Unmarshal(m, b) -} -func (m *CompiledQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledQuery.Marshal(b, m, deterministic) -} -func (dst *CompiledQuery) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledQuery.Merge(dst, src) -} -func (m *CompiledQuery) XXX_Size() int { - return xxx_messageInfo_CompiledQuery.Size(m) -} -func (m *CompiledQuery) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledQuery.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledQuery proto.InternalMessageInfo - -const Default_CompiledQuery_Offset int32 = 0 - -func (m *CompiledQuery) GetPrimaryscan() *CompiledQuery_PrimaryScan { - if m != nil { - return m.Primaryscan - } - return nil -} - -func (m *CompiledQuery) GetMergejoinscan() []*CompiledQuery_MergeJoinScan { - if m != nil { - return m.Mergejoinscan - } - return nil -} - -func (m *CompiledQuery) GetIndexDef() *Index { - if m != nil { - return m.IndexDef - } - return nil -} - -func (m *CompiledQuery) GetOffset() int32 { - if m != nil && m.Offset != nil { - return *m.Offset - } - return Default_CompiledQuery_Offset -} - -func (m *CompiledQuery) GetLimit() int32 { - if m != nil && m.Limit != nil { - return *m.Limit - } - return 0 -} - -func (m *CompiledQuery) GetKeysOnly() bool { - if m != nil && m.KeysOnly != nil { - return *m.KeysOnly - } - return false -} - -func (m *CompiledQuery) GetPropertyName() []string { - if m != nil { - return m.PropertyName - } - return nil -} - -func (m *CompiledQuery) GetDistinctInfixSize() int32 { - if m != nil && m.DistinctInfixSize != nil { - return *m.DistinctInfixSize - } - return 0 -} - -func (m *CompiledQuery) GetEntityfilter() *CompiledQuery_EntityFilter { - if m != nil { - return m.Entityfilter - } - return nil -} - -type CompiledQuery_PrimaryScan struct { - IndexName *string `protobuf:"bytes,2,opt,name=index_name,json=indexName" json:"index_name,omitempty"` - StartKey *string `protobuf:"bytes,3,opt,name=start_key,json=startKey" json:"start_key,omitempty"` - StartInclusive *bool `protobuf:"varint,4,opt,name=start_inclusive,json=startInclusive" json:"start_inclusive,omitempty"` - EndKey *string `protobuf:"bytes,5,opt,name=end_key,json=endKey" json:"end_key,omitempty"` - EndInclusive *bool `protobuf:"varint,6,opt,name=end_inclusive,json=endInclusive" json:"end_inclusive,omitempty"` - StartPostfixValue []string `protobuf:"bytes,22,rep,name=start_postfix_value,json=startPostfixValue" json:"start_postfix_value,omitempty"` - EndPostfixValue []string `protobuf:"bytes,23,rep,name=end_postfix_value,json=endPostfixValue" json:"end_postfix_value,omitempty"` - EndUnappliedLogTimestampUs *int64 `protobuf:"varint,19,opt,name=end_unapplied_log_timestamp_us,json=endUnappliedLogTimestampUs" json:"end_unapplied_log_timestamp_us,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledQuery_PrimaryScan) Reset() { *m = CompiledQuery_PrimaryScan{} } -func (m *CompiledQuery_PrimaryScan) String() string { return proto.CompactTextString(m) } -func (*CompiledQuery_PrimaryScan) ProtoMessage() {} -func (*CompiledQuery_PrimaryScan) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 0} -} -func (m *CompiledQuery_PrimaryScan) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledQuery_PrimaryScan.Unmarshal(m, b) -} -func (m *CompiledQuery_PrimaryScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledQuery_PrimaryScan.Marshal(b, m, deterministic) -} -func (dst *CompiledQuery_PrimaryScan) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledQuery_PrimaryScan.Merge(dst, src) -} -func (m *CompiledQuery_PrimaryScan) XXX_Size() int { - return xxx_messageInfo_CompiledQuery_PrimaryScan.Size(m) -} -func (m *CompiledQuery_PrimaryScan) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledQuery_PrimaryScan.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledQuery_PrimaryScan proto.InternalMessageInfo - -func (m *CompiledQuery_PrimaryScan) GetIndexName() string { - if m != nil && m.IndexName != nil { - return *m.IndexName - } - return "" -} - -func (m *CompiledQuery_PrimaryScan) GetStartKey() string { - if m != nil && m.StartKey != nil { - return *m.StartKey - } - return "" -} - -func (m *CompiledQuery_PrimaryScan) GetStartInclusive() bool { - if m != nil && m.StartInclusive != nil { - return *m.StartInclusive - } - return false -} - -func (m *CompiledQuery_PrimaryScan) GetEndKey() string { - if m != nil && m.EndKey != nil { - return *m.EndKey - } - return "" -} - -func (m *CompiledQuery_PrimaryScan) GetEndInclusive() bool { - if m != nil && m.EndInclusive != nil { - return *m.EndInclusive - } - return false -} - -func (m *CompiledQuery_PrimaryScan) GetStartPostfixValue() []string { - if m != nil { - return m.StartPostfixValue - } - return nil -} - -func (m *CompiledQuery_PrimaryScan) GetEndPostfixValue() []string { - if m != nil { - return m.EndPostfixValue - } - return nil -} - -func (m *CompiledQuery_PrimaryScan) GetEndUnappliedLogTimestampUs() int64 { - if m != nil && m.EndUnappliedLogTimestampUs != nil { - return *m.EndUnappliedLogTimestampUs - } - return 0 -} - -type CompiledQuery_MergeJoinScan struct { - IndexName *string `protobuf:"bytes,8,req,name=index_name,json=indexName" json:"index_name,omitempty"` - PrefixValue []string `protobuf:"bytes,9,rep,name=prefix_value,json=prefixValue" json:"prefix_value,omitempty"` - ValuePrefix *bool `protobuf:"varint,20,opt,name=value_prefix,json=valuePrefix,def=0" json:"value_prefix,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledQuery_MergeJoinScan) Reset() { *m = CompiledQuery_MergeJoinScan{} } -func (m *CompiledQuery_MergeJoinScan) String() string { return proto.CompactTextString(m) } -func (*CompiledQuery_MergeJoinScan) ProtoMessage() {} -func (*CompiledQuery_MergeJoinScan) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 1} -} -func (m *CompiledQuery_MergeJoinScan) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledQuery_MergeJoinScan.Unmarshal(m, b) -} -func (m *CompiledQuery_MergeJoinScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledQuery_MergeJoinScan.Marshal(b, m, deterministic) -} -func (dst *CompiledQuery_MergeJoinScan) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledQuery_MergeJoinScan.Merge(dst, src) -} -func (m *CompiledQuery_MergeJoinScan) XXX_Size() int { - return xxx_messageInfo_CompiledQuery_MergeJoinScan.Size(m) -} -func (m *CompiledQuery_MergeJoinScan) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledQuery_MergeJoinScan.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledQuery_MergeJoinScan proto.InternalMessageInfo - -const Default_CompiledQuery_MergeJoinScan_ValuePrefix bool = false - -func (m *CompiledQuery_MergeJoinScan) GetIndexName() string { - if m != nil && m.IndexName != nil { - return *m.IndexName - } - return "" -} - -func (m *CompiledQuery_MergeJoinScan) GetPrefixValue() []string { - if m != nil { - return m.PrefixValue - } - return nil -} - -func (m *CompiledQuery_MergeJoinScan) GetValuePrefix() bool { - if m != nil && m.ValuePrefix != nil { - return *m.ValuePrefix - } - return Default_CompiledQuery_MergeJoinScan_ValuePrefix -} - -type CompiledQuery_EntityFilter struct { - Distinct *bool `protobuf:"varint,14,opt,name=distinct,def=0" json:"distinct,omitempty"` - Kind *string `protobuf:"bytes,17,opt,name=kind" json:"kind,omitempty"` - Ancestor *Reference `protobuf:"bytes,18,opt,name=ancestor" json:"ancestor,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledQuery_EntityFilter) Reset() { *m = CompiledQuery_EntityFilter{} } -func (m *CompiledQuery_EntityFilter) String() string { return proto.CompactTextString(m) } -func (*CompiledQuery_EntityFilter) ProtoMessage() {} -func (*CompiledQuery_EntityFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 2} -} -func (m *CompiledQuery_EntityFilter) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledQuery_EntityFilter.Unmarshal(m, b) -} -func (m *CompiledQuery_EntityFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledQuery_EntityFilter.Marshal(b, m, deterministic) -} -func (dst *CompiledQuery_EntityFilter) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledQuery_EntityFilter.Merge(dst, src) -} -func (m *CompiledQuery_EntityFilter) XXX_Size() int { - return xxx_messageInfo_CompiledQuery_EntityFilter.Size(m) -} -func (m *CompiledQuery_EntityFilter) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledQuery_EntityFilter.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledQuery_EntityFilter proto.InternalMessageInfo - -const Default_CompiledQuery_EntityFilter_Distinct bool = false - -func (m *CompiledQuery_EntityFilter) GetDistinct() bool { - if m != nil && m.Distinct != nil { - return *m.Distinct - } - return Default_CompiledQuery_EntityFilter_Distinct -} - -func (m *CompiledQuery_EntityFilter) GetKind() string { - if m != nil && m.Kind != nil { - return *m.Kind - } - return "" -} - -func (m *CompiledQuery_EntityFilter) GetAncestor() *Reference { - if m != nil { - return m.Ancestor - } - return nil -} - -type CompiledCursor struct { - Position *CompiledCursor_Position `protobuf:"group,2,opt,name=Position,json=position" json:"position,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledCursor) Reset() { *m = CompiledCursor{} } -func (m *CompiledCursor) String() string { return proto.CompactTextString(m) } -func (*CompiledCursor) ProtoMessage() {} -func (*CompiledCursor) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17} -} -func (m *CompiledCursor) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledCursor.Unmarshal(m, b) -} -func (m *CompiledCursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledCursor.Marshal(b, m, deterministic) -} -func (dst *CompiledCursor) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledCursor.Merge(dst, src) -} -func (m *CompiledCursor) XXX_Size() int { - return xxx_messageInfo_CompiledCursor.Size(m) -} -func (m *CompiledCursor) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledCursor.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledCursor proto.InternalMessageInfo - -func (m *CompiledCursor) GetPosition() *CompiledCursor_Position { - if m != nil { - return m.Position - } - return nil -} - -type CompiledCursor_Position struct { - StartKey *string `protobuf:"bytes,27,opt,name=start_key,json=startKey" json:"start_key,omitempty"` - Indexvalue []*CompiledCursor_Position_IndexValue `protobuf:"group,29,rep,name=IndexValue,json=indexvalue" json:"indexvalue,omitempty"` - Key *Reference `protobuf:"bytes,32,opt,name=key" json:"key,omitempty"` - StartInclusive *bool `protobuf:"varint,28,opt,name=start_inclusive,json=startInclusive,def=1" json:"start_inclusive,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledCursor_Position) Reset() { *m = CompiledCursor_Position{} } -func (m *CompiledCursor_Position) String() string { return proto.CompactTextString(m) } -func (*CompiledCursor_Position) ProtoMessage() {} -func (*CompiledCursor_Position) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0} -} -func (m *CompiledCursor_Position) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledCursor_Position.Unmarshal(m, b) -} -func (m *CompiledCursor_Position) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledCursor_Position.Marshal(b, m, deterministic) -} -func (dst *CompiledCursor_Position) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledCursor_Position.Merge(dst, src) -} -func (m *CompiledCursor_Position) XXX_Size() int { - return xxx_messageInfo_CompiledCursor_Position.Size(m) -} -func (m *CompiledCursor_Position) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledCursor_Position.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledCursor_Position proto.InternalMessageInfo - -const Default_CompiledCursor_Position_StartInclusive bool = true - -func (m *CompiledCursor_Position) GetStartKey() string { - if m != nil && m.StartKey != nil { - return *m.StartKey - } - return "" -} - -func (m *CompiledCursor_Position) GetIndexvalue() []*CompiledCursor_Position_IndexValue { - if m != nil { - return m.Indexvalue - } - return nil -} - -func (m *CompiledCursor_Position) GetKey() *Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *CompiledCursor_Position) GetStartInclusive() bool { - if m != nil && m.StartInclusive != nil { - return *m.StartInclusive - } - return Default_CompiledCursor_Position_StartInclusive -} - -type CompiledCursor_Position_IndexValue struct { - Property *string `protobuf:"bytes,30,opt,name=property" json:"property,omitempty"` - Value *PropertyValue `protobuf:"bytes,31,req,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompiledCursor_Position_IndexValue) Reset() { *m = CompiledCursor_Position_IndexValue{} } -func (m *CompiledCursor_Position_IndexValue) String() string { return proto.CompactTextString(m) } -func (*CompiledCursor_Position_IndexValue) ProtoMessage() {} -func (*CompiledCursor_Position_IndexValue) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0, 0} -} -func (m *CompiledCursor_Position_IndexValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompiledCursor_Position_IndexValue.Unmarshal(m, b) -} -func (m *CompiledCursor_Position_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompiledCursor_Position_IndexValue.Marshal(b, m, deterministic) -} -func (dst *CompiledCursor_Position_IndexValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompiledCursor_Position_IndexValue.Merge(dst, src) -} -func (m *CompiledCursor_Position_IndexValue) XXX_Size() int { - return xxx_messageInfo_CompiledCursor_Position_IndexValue.Size(m) -} -func (m *CompiledCursor_Position_IndexValue) XXX_DiscardUnknown() { - xxx_messageInfo_CompiledCursor_Position_IndexValue.DiscardUnknown(m) -} - -var xxx_messageInfo_CompiledCursor_Position_IndexValue proto.InternalMessageInfo - -func (m *CompiledCursor_Position_IndexValue) GetProperty() string { - if m != nil && m.Property != nil { - return *m.Property - } - return "" -} - -func (m *CompiledCursor_Position_IndexValue) GetValue() *PropertyValue { - if m != nil { - return m.Value - } - return nil -} - -type Cursor struct { - Cursor *uint64 `protobuf:"fixed64,1,req,name=cursor" json:"cursor,omitempty"` - App *string `protobuf:"bytes,2,opt,name=app" json:"app,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Cursor) Reset() { *m = Cursor{} } -func (m *Cursor) String() string { return proto.CompactTextString(m) } -func (*Cursor) ProtoMessage() {} -func (*Cursor) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{18} -} -func (m *Cursor) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Cursor.Unmarshal(m, b) -} -func (m *Cursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Cursor.Marshal(b, m, deterministic) -} -func (dst *Cursor) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cursor.Merge(dst, src) -} -func (m *Cursor) XXX_Size() int { - return xxx_messageInfo_Cursor.Size(m) -} -func (m *Cursor) XXX_DiscardUnknown() { - xxx_messageInfo_Cursor.DiscardUnknown(m) -} - -var xxx_messageInfo_Cursor proto.InternalMessageInfo - -func (m *Cursor) GetCursor() uint64 { - if m != nil && m.Cursor != nil { - return *m.Cursor - } - return 0 -} - -func (m *Cursor) GetApp() string { - if m != nil && m.App != nil { - return *m.App - } - return "" -} - -type Error struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Error) Reset() { *m = Error{} } -func (m *Error) String() string { return proto.CompactTextString(m) } -func (*Error) ProtoMessage() {} -func (*Error) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19} -} -func (m *Error) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Error.Unmarshal(m, b) -} -func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Error.Marshal(b, m, deterministic) -} -func (dst *Error) XXX_Merge(src proto.Message) { - xxx_messageInfo_Error.Merge(dst, src) -} -func (m *Error) XXX_Size() int { - return xxx_messageInfo_Error.Size(m) -} -func (m *Error) XXX_DiscardUnknown() { - xxx_messageInfo_Error.DiscardUnknown(m) -} - -var xxx_messageInfo_Error proto.InternalMessageInfo - -type Cost struct { - IndexWrites *int32 `protobuf:"varint,1,opt,name=index_writes,json=indexWrites" json:"index_writes,omitempty"` - IndexWriteBytes *int32 `protobuf:"varint,2,opt,name=index_write_bytes,json=indexWriteBytes" json:"index_write_bytes,omitempty"` - EntityWrites *int32 `protobuf:"varint,3,opt,name=entity_writes,json=entityWrites" json:"entity_writes,omitempty"` - EntityWriteBytes *int32 `protobuf:"varint,4,opt,name=entity_write_bytes,json=entityWriteBytes" json:"entity_write_bytes,omitempty"` - Commitcost *Cost_CommitCost `protobuf:"group,5,opt,name=CommitCost,json=commitcost" json:"commitcost,omitempty"` - ApproximateStorageDelta *int32 `protobuf:"varint,8,opt,name=approximate_storage_delta,json=approximateStorageDelta" json:"approximate_storage_delta,omitempty"` - IdSequenceUpdates *int32 `protobuf:"varint,9,opt,name=id_sequence_updates,json=idSequenceUpdates" json:"id_sequence_updates,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Cost) Reset() { *m = Cost{} } -func (m *Cost) String() string { return proto.CompactTextString(m) } -func (*Cost) ProtoMessage() {} -func (*Cost) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20} -} -func (m *Cost) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Cost.Unmarshal(m, b) -} -func (m *Cost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Cost.Marshal(b, m, deterministic) -} -func (dst *Cost) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cost.Merge(dst, src) -} -func (m *Cost) XXX_Size() int { - return xxx_messageInfo_Cost.Size(m) -} -func (m *Cost) XXX_DiscardUnknown() { - xxx_messageInfo_Cost.DiscardUnknown(m) -} - -var xxx_messageInfo_Cost proto.InternalMessageInfo - -func (m *Cost) GetIndexWrites() int32 { - if m != nil && m.IndexWrites != nil { - return *m.IndexWrites - } - return 0 -} - -func (m *Cost) GetIndexWriteBytes() int32 { - if m != nil && m.IndexWriteBytes != nil { - return *m.IndexWriteBytes - } - return 0 -} - -func (m *Cost) GetEntityWrites() int32 { - if m != nil && m.EntityWrites != nil { - return *m.EntityWrites - } - return 0 -} - -func (m *Cost) GetEntityWriteBytes() int32 { - if m != nil && m.EntityWriteBytes != nil { - return *m.EntityWriteBytes - } - return 0 -} - -func (m *Cost) GetCommitcost() *Cost_CommitCost { - if m != nil { - return m.Commitcost - } - return nil -} - -func (m *Cost) GetApproximateStorageDelta() int32 { - if m != nil && m.ApproximateStorageDelta != nil { - return *m.ApproximateStorageDelta - } - return 0 -} - -func (m *Cost) GetIdSequenceUpdates() int32 { - if m != nil && m.IdSequenceUpdates != nil { - return *m.IdSequenceUpdates - } - return 0 -} - -type Cost_CommitCost struct { - RequestedEntityPuts *int32 `protobuf:"varint,6,opt,name=requested_entity_puts,json=requestedEntityPuts" json:"requested_entity_puts,omitempty"` - RequestedEntityDeletes *int32 `protobuf:"varint,7,opt,name=requested_entity_deletes,json=requestedEntityDeletes" json:"requested_entity_deletes,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Cost_CommitCost) Reset() { *m = Cost_CommitCost{} } -func (m *Cost_CommitCost) String() string { return proto.CompactTextString(m) } -func (*Cost_CommitCost) ProtoMessage() {} -func (*Cost_CommitCost) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20, 0} -} -func (m *Cost_CommitCost) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Cost_CommitCost.Unmarshal(m, b) -} -func (m *Cost_CommitCost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Cost_CommitCost.Marshal(b, m, deterministic) -} -func (dst *Cost_CommitCost) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cost_CommitCost.Merge(dst, src) -} -func (m *Cost_CommitCost) XXX_Size() int { - return xxx_messageInfo_Cost_CommitCost.Size(m) -} -func (m *Cost_CommitCost) XXX_DiscardUnknown() { - xxx_messageInfo_Cost_CommitCost.DiscardUnknown(m) -} - -var xxx_messageInfo_Cost_CommitCost proto.InternalMessageInfo - -func (m *Cost_CommitCost) GetRequestedEntityPuts() int32 { - if m != nil && m.RequestedEntityPuts != nil { - return *m.RequestedEntityPuts - } - return 0 -} - -func (m *Cost_CommitCost) GetRequestedEntityDeletes() int32 { - if m != nil && m.RequestedEntityDeletes != nil { - return *m.RequestedEntityDeletes - } - return 0 -} - -type GetRequest struct { - Header *InternalHeader `protobuf:"bytes,6,opt,name=header" json:"header,omitempty"` - Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` - Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"` - FailoverMs *int64 `protobuf:"varint,3,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"` - Strong *bool `protobuf:"varint,4,opt,name=strong" json:"strong,omitempty"` - AllowDeferred *bool `protobuf:"varint,5,opt,name=allow_deferred,json=allowDeferred,def=0" json:"allow_deferred,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetRequest) Reset() { *m = GetRequest{} } -func (m *GetRequest) String() string { return proto.CompactTextString(m) } -func (*GetRequest) ProtoMessage() {} -func (*GetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{21} -} -func (m *GetRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetRequest.Unmarshal(m, b) -} -func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic) -} -func (dst *GetRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetRequest.Merge(dst, src) -} -func (m *GetRequest) XXX_Size() int { - return xxx_messageInfo_GetRequest.Size(m) -} -func (m *GetRequest) XXX_DiscardUnknown() { - xxx_messageInfo_GetRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_GetRequest proto.InternalMessageInfo - -const Default_GetRequest_AllowDeferred bool = false - -func (m *GetRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *GetRequest) GetKey() []*Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *GetRequest) GetTransaction() *Transaction { - if m != nil { - return m.Transaction - } - return nil -} - -func (m *GetRequest) GetFailoverMs() int64 { - if m != nil && m.FailoverMs != nil { - return *m.FailoverMs - } - return 0 -} - -func (m *GetRequest) GetStrong() bool { - if m != nil && m.Strong != nil { - return *m.Strong - } - return false -} - -func (m *GetRequest) GetAllowDeferred() bool { - if m != nil && m.AllowDeferred != nil { - return *m.AllowDeferred - } - return Default_GetRequest_AllowDeferred -} - -type GetResponse struct { - Entity []*GetResponse_Entity `protobuf:"group,1,rep,name=Entity,json=entity" json:"entity,omitempty"` - Deferred []*Reference `protobuf:"bytes,5,rep,name=deferred" json:"deferred,omitempty"` - InOrder *bool `protobuf:"varint,6,opt,name=in_order,json=inOrder,def=1" json:"in_order,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetResponse) Reset() { *m = GetResponse{} } -func (m *GetResponse) String() string { return proto.CompactTextString(m) } -func (*GetResponse) ProtoMessage() {} -func (*GetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22} -} -func (m *GetResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetResponse.Unmarshal(m, b) -} -func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic) -} -func (dst *GetResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetResponse.Merge(dst, src) -} -func (m *GetResponse) XXX_Size() int { - return xxx_messageInfo_GetResponse.Size(m) -} -func (m *GetResponse) XXX_DiscardUnknown() { - xxx_messageInfo_GetResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_GetResponse proto.InternalMessageInfo - -const Default_GetResponse_InOrder bool = true - -func (m *GetResponse) GetEntity() []*GetResponse_Entity { - if m != nil { - return m.Entity - } - return nil -} - -func (m *GetResponse) GetDeferred() []*Reference { - if m != nil { - return m.Deferred - } - return nil -} - -func (m *GetResponse) GetInOrder() bool { - if m != nil && m.InOrder != nil { - return *m.InOrder - } - return Default_GetResponse_InOrder -} - -type GetResponse_Entity struct { - Entity *EntityProto `protobuf:"bytes,2,opt,name=entity" json:"entity,omitempty"` - Key *Reference `protobuf:"bytes,4,opt,name=key" json:"key,omitempty"` - Version *int64 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetResponse_Entity) Reset() { *m = GetResponse_Entity{} } -func (m *GetResponse_Entity) String() string { return proto.CompactTextString(m) } -func (*GetResponse_Entity) ProtoMessage() {} -func (*GetResponse_Entity) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22, 0} -} -func (m *GetResponse_Entity) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetResponse_Entity.Unmarshal(m, b) -} -func (m *GetResponse_Entity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetResponse_Entity.Marshal(b, m, deterministic) -} -func (dst *GetResponse_Entity) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetResponse_Entity.Merge(dst, src) -} -func (m *GetResponse_Entity) XXX_Size() int { - return xxx_messageInfo_GetResponse_Entity.Size(m) -} -func (m *GetResponse_Entity) XXX_DiscardUnknown() { - xxx_messageInfo_GetResponse_Entity.DiscardUnknown(m) -} - -var xxx_messageInfo_GetResponse_Entity proto.InternalMessageInfo - -func (m *GetResponse_Entity) GetEntity() *EntityProto { - if m != nil { - return m.Entity - } - return nil -} - -func (m *GetResponse_Entity) GetKey() *Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *GetResponse_Entity) GetVersion() int64 { - if m != nil && m.Version != nil { - return *m.Version - } - return 0 -} - -type PutRequest struct { - Header *InternalHeader `protobuf:"bytes,11,opt,name=header" json:"header,omitempty"` - Entity []*EntityProto `protobuf:"bytes,1,rep,name=entity" json:"entity,omitempty"` - Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"` - CompositeIndex []*CompositeIndex `protobuf:"bytes,3,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"` - Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"` - Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"` - MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"` - Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"` - AutoIdPolicy *PutRequest_AutoIdPolicy `protobuf:"varint,10,opt,name=auto_id_policy,json=autoIdPolicy,enum=appengine.PutRequest_AutoIdPolicy,def=0" json:"auto_id_policy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PutRequest) Reset() { *m = PutRequest{} } -func (m *PutRequest) String() string { return proto.CompactTextString(m) } -func (*PutRequest) ProtoMessage() {} -func (*PutRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23} -} -func (m *PutRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PutRequest.Unmarshal(m, b) -} -func (m *PutRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PutRequest.Marshal(b, m, deterministic) -} -func (dst *PutRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PutRequest.Merge(dst, src) -} -func (m *PutRequest) XXX_Size() int { - return xxx_messageInfo_PutRequest.Size(m) -} -func (m *PutRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PutRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PutRequest proto.InternalMessageInfo - -const Default_PutRequest_Trusted bool = false -const Default_PutRequest_Force bool = false -const Default_PutRequest_MarkChanges bool = false -const Default_PutRequest_AutoIdPolicy PutRequest_AutoIdPolicy = PutRequest_CURRENT - -func (m *PutRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *PutRequest) GetEntity() []*EntityProto { - if m != nil { - return m.Entity - } - return nil -} - -func (m *PutRequest) GetTransaction() *Transaction { - if m != nil { - return m.Transaction - } - return nil -} - -func (m *PutRequest) GetCompositeIndex() []*CompositeIndex { - if m != nil { - return m.CompositeIndex - } - return nil -} - -func (m *PutRequest) GetTrusted() bool { - if m != nil && m.Trusted != nil { - return *m.Trusted - } - return Default_PutRequest_Trusted -} - -func (m *PutRequest) GetForce() bool { - if m != nil && m.Force != nil { - return *m.Force - } - return Default_PutRequest_Force -} - -func (m *PutRequest) GetMarkChanges() bool { - if m != nil && m.MarkChanges != nil { - return *m.MarkChanges - } - return Default_PutRequest_MarkChanges -} - -func (m *PutRequest) GetSnapshot() []*Snapshot { - if m != nil { - return m.Snapshot - } - return nil -} - -func (m *PutRequest) GetAutoIdPolicy() PutRequest_AutoIdPolicy { - if m != nil && m.AutoIdPolicy != nil { - return *m.AutoIdPolicy - } - return Default_PutRequest_AutoIdPolicy -} - -type PutResponse struct { - Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` - Cost *Cost `protobuf:"bytes,2,opt,name=cost" json:"cost,omitempty"` - Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PutResponse) Reset() { *m = PutResponse{} } -func (m *PutResponse) String() string { return proto.CompactTextString(m) } -func (*PutResponse) ProtoMessage() {} -func (*PutResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{24} -} -func (m *PutResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PutResponse.Unmarshal(m, b) -} -func (m *PutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PutResponse.Marshal(b, m, deterministic) -} -func (dst *PutResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PutResponse.Merge(dst, src) -} -func (m *PutResponse) XXX_Size() int { - return xxx_messageInfo_PutResponse.Size(m) -} -func (m *PutResponse) XXX_DiscardUnknown() { - xxx_messageInfo_PutResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_PutResponse proto.InternalMessageInfo - -func (m *PutResponse) GetKey() []*Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *PutResponse) GetCost() *Cost { - if m != nil { - return m.Cost - } - return nil -} - -func (m *PutResponse) GetVersion() []int64 { - if m != nil { - return m.Version - } - return nil -} - -type TouchRequest struct { - Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"` - Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` - CompositeIndex []*CompositeIndex `protobuf:"bytes,2,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"` - Force *bool `protobuf:"varint,3,opt,name=force,def=0" json:"force,omitempty"` - Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TouchRequest) Reset() { *m = TouchRequest{} } -func (m *TouchRequest) String() string { return proto.CompactTextString(m) } -func (*TouchRequest) ProtoMessage() {} -func (*TouchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{25} -} -func (m *TouchRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TouchRequest.Unmarshal(m, b) -} -func (m *TouchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TouchRequest.Marshal(b, m, deterministic) -} -func (dst *TouchRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_TouchRequest.Merge(dst, src) -} -func (m *TouchRequest) XXX_Size() int { - return xxx_messageInfo_TouchRequest.Size(m) -} -func (m *TouchRequest) XXX_DiscardUnknown() { - xxx_messageInfo_TouchRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_TouchRequest proto.InternalMessageInfo - -const Default_TouchRequest_Force bool = false - -func (m *TouchRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *TouchRequest) GetKey() []*Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *TouchRequest) GetCompositeIndex() []*CompositeIndex { - if m != nil { - return m.CompositeIndex - } - return nil -} - -func (m *TouchRequest) GetForce() bool { - if m != nil && m.Force != nil { - return *m.Force - } - return Default_TouchRequest_Force -} - -func (m *TouchRequest) GetSnapshot() []*Snapshot { - if m != nil { - return m.Snapshot - } - return nil -} - -type TouchResponse struct { - Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TouchResponse) Reset() { *m = TouchResponse{} } -func (m *TouchResponse) String() string { return proto.CompactTextString(m) } -func (*TouchResponse) ProtoMessage() {} -func (*TouchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{26} -} -func (m *TouchResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TouchResponse.Unmarshal(m, b) -} -func (m *TouchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TouchResponse.Marshal(b, m, deterministic) -} -func (dst *TouchResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_TouchResponse.Merge(dst, src) -} -func (m *TouchResponse) XXX_Size() int { - return xxx_messageInfo_TouchResponse.Size(m) -} -func (m *TouchResponse) XXX_DiscardUnknown() { - xxx_messageInfo_TouchResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_TouchResponse proto.InternalMessageInfo - -func (m *TouchResponse) GetCost() *Cost { - if m != nil { - return m.Cost - } - return nil -} - -type DeleteRequest struct { - Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"` - Key []*Reference `protobuf:"bytes,6,rep,name=key" json:"key,omitempty"` - Transaction *Transaction `protobuf:"bytes,5,opt,name=transaction" json:"transaction,omitempty"` - Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"` - Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"` - MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"` - Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeleteRequest) Reset() { *m = DeleteRequest{} } -func (m *DeleteRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteRequest) ProtoMessage() {} -func (*DeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{27} -} -func (m *DeleteRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteRequest.Unmarshal(m, b) -} -func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic) -} -func (dst *DeleteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteRequest.Merge(dst, src) -} -func (m *DeleteRequest) XXX_Size() int { - return xxx_messageInfo_DeleteRequest.Size(m) -} -func (m *DeleteRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo - -const Default_DeleteRequest_Trusted bool = false -const Default_DeleteRequest_Force bool = false -const Default_DeleteRequest_MarkChanges bool = false - -func (m *DeleteRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *DeleteRequest) GetKey() []*Reference { - if m != nil { - return m.Key - } - return nil -} - -func (m *DeleteRequest) GetTransaction() *Transaction { - if m != nil { - return m.Transaction - } - return nil -} - -func (m *DeleteRequest) GetTrusted() bool { - if m != nil && m.Trusted != nil { - return *m.Trusted - } - return Default_DeleteRequest_Trusted -} - -func (m *DeleteRequest) GetForce() bool { - if m != nil && m.Force != nil { - return *m.Force - } - return Default_DeleteRequest_Force -} - -func (m *DeleteRequest) GetMarkChanges() bool { - if m != nil && m.MarkChanges != nil { - return *m.MarkChanges - } - return Default_DeleteRequest_MarkChanges -} - -func (m *DeleteRequest) GetSnapshot() []*Snapshot { - if m != nil { - return m.Snapshot - } - return nil -} - -type DeleteResponse struct { - Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"` - Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeleteResponse) Reset() { *m = DeleteResponse{} } -func (m *DeleteResponse) String() string { return proto.CompactTextString(m) } -func (*DeleteResponse) ProtoMessage() {} -func (*DeleteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{28} -} -func (m *DeleteResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteResponse.Unmarshal(m, b) -} -func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic) -} -func (dst *DeleteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteResponse.Merge(dst, src) -} -func (m *DeleteResponse) XXX_Size() int { - return xxx_messageInfo_DeleteResponse.Size(m) -} -func (m *DeleteResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo - -func (m *DeleteResponse) GetCost() *Cost { - if m != nil { - return m.Cost - } - return nil -} - -func (m *DeleteResponse) GetVersion() []int64 { - if m != nil { - return m.Version - } - return nil -} - -type NextRequest struct { - Header *InternalHeader `protobuf:"bytes,5,opt,name=header" json:"header,omitempty"` - Cursor *Cursor `protobuf:"bytes,1,req,name=cursor" json:"cursor,omitempty"` - Count *int32 `protobuf:"varint,2,opt,name=count" json:"count,omitempty"` - Offset *int32 `protobuf:"varint,4,opt,name=offset,def=0" json:"offset,omitempty"` - Compile *bool `protobuf:"varint,3,opt,name=compile,def=0" json:"compile,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *NextRequest) Reset() { *m = NextRequest{} } -func (m *NextRequest) String() string { return proto.CompactTextString(m) } -func (*NextRequest) ProtoMessage() {} -func (*NextRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{29} -} -func (m *NextRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_NextRequest.Unmarshal(m, b) -} -func (m *NextRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_NextRequest.Marshal(b, m, deterministic) -} -func (dst *NextRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_NextRequest.Merge(dst, src) -} -func (m *NextRequest) XXX_Size() int { - return xxx_messageInfo_NextRequest.Size(m) -} -func (m *NextRequest) XXX_DiscardUnknown() { - xxx_messageInfo_NextRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_NextRequest proto.InternalMessageInfo - -const Default_NextRequest_Offset int32 = 0 -const Default_NextRequest_Compile bool = false - -func (m *NextRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *NextRequest) GetCursor() *Cursor { - if m != nil { - return m.Cursor - } - return nil -} - -func (m *NextRequest) GetCount() int32 { - if m != nil && m.Count != nil { - return *m.Count - } - return 0 -} - -func (m *NextRequest) GetOffset() int32 { - if m != nil && m.Offset != nil { - return *m.Offset - } - return Default_NextRequest_Offset -} - -func (m *NextRequest) GetCompile() bool { - if m != nil && m.Compile != nil { - return *m.Compile - } - return Default_NextRequest_Compile -} - -type QueryResult struct { - Cursor *Cursor `protobuf:"bytes,1,opt,name=cursor" json:"cursor,omitempty"` - Result []*EntityProto `protobuf:"bytes,2,rep,name=result" json:"result,omitempty"` - SkippedResults *int32 `protobuf:"varint,7,opt,name=skipped_results,json=skippedResults" json:"skipped_results,omitempty"` - MoreResults *bool `protobuf:"varint,3,req,name=more_results,json=moreResults" json:"more_results,omitempty"` - KeysOnly *bool `protobuf:"varint,4,opt,name=keys_only,json=keysOnly" json:"keys_only,omitempty"` - IndexOnly *bool `protobuf:"varint,9,opt,name=index_only,json=indexOnly" json:"index_only,omitempty"` - SmallOps *bool `protobuf:"varint,10,opt,name=small_ops,json=smallOps" json:"small_ops,omitempty"` - CompiledQuery *CompiledQuery `protobuf:"bytes,5,opt,name=compiled_query,json=compiledQuery" json:"compiled_query,omitempty"` - CompiledCursor *CompiledCursor `protobuf:"bytes,6,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"` - Index []*CompositeIndex `protobuf:"bytes,8,rep,name=index" json:"index,omitempty"` - Version []int64 `protobuf:"varint,11,rep,name=version" json:"version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *QueryResult) Reset() { *m = QueryResult{} } -func (m *QueryResult) String() string { return proto.CompactTextString(m) } -func (*QueryResult) ProtoMessage() {} -func (*QueryResult) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{30} -} -func (m *QueryResult) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_QueryResult.Unmarshal(m, b) -} -func (m *QueryResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_QueryResult.Marshal(b, m, deterministic) -} -func (dst *QueryResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryResult.Merge(dst, src) -} -func (m *QueryResult) XXX_Size() int { - return xxx_messageInfo_QueryResult.Size(m) -} -func (m *QueryResult) XXX_DiscardUnknown() { - xxx_messageInfo_QueryResult.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryResult proto.InternalMessageInfo - -func (m *QueryResult) GetCursor() *Cursor { - if m != nil { - return m.Cursor - } - return nil -} - -func (m *QueryResult) GetResult() []*EntityProto { - if m != nil { - return m.Result - } - return nil -} - -func (m *QueryResult) GetSkippedResults() int32 { - if m != nil && m.SkippedResults != nil { - return *m.SkippedResults - } - return 0 -} - -func (m *QueryResult) GetMoreResults() bool { - if m != nil && m.MoreResults != nil { - return *m.MoreResults - } - return false -} - -func (m *QueryResult) GetKeysOnly() bool { - if m != nil && m.KeysOnly != nil { - return *m.KeysOnly - } - return false -} - -func (m *QueryResult) GetIndexOnly() bool { - if m != nil && m.IndexOnly != nil { - return *m.IndexOnly - } - return false -} - -func (m *QueryResult) GetSmallOps() bool { - if m != nil && m.SmallOps != nil { - return *m.SmallOps - } - return false -} - -func (m *QueryResult) GetCompiledQuery() *CompiledQuery { - if m != nil { - return m.CompiledQuery - } - return nil -} - -func (m *QueryResult) GetCompiledCursor() *CompiledCursor { - if m != nil { - return m.CompiledCursor - } - return nil -} - -func (m *QueryResult) GetIndex() []*CompositeIndex { - if m != nil { - return m.Index - } - return nil -} - -func (m *QueryResult) GetVersion() []int64 { - if m != nil { - return m.Version - } - return nil -} - -type AllocateIdsRequest struct { - Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"` - ModelKey *Reference `protobuf:"bytes,1,opt,name=model_key,json=modelKey" json:"model_key,omitempty"` - Size *int64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"` - Max *int64 `protobuf:"varint,3,opt,name=max" json:"max,omitempty"` - Reserve []*Reference `protobuf:"bytes,5,rep,name=reserve" json:"reserve,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AllocateIdsRequest) Reset() { *m = AllocateIdsRequest{} } -func (m *AllocateIdsRequest) String() string { return proto.CompactTextString(m) } -func (*AllocateIdsRequest) ProtoMessage() {} -func (*AllocateIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{31} -} -func (m *AllocateIdsRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AllocateIdsRequest.Unmarshal(m, b) -} -func (m *AllocateIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AllocateIdsRequest.Marshal(b, m, deterministic) -} -func (dst *AllocateIdsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllocateIdsRequest.Merge(dst, src) -} -func (m *AllocateIdsRequest) XXX_Size() int { - return xxx_messageInfo_AllocateIdsRequest.Size(m) -} -func (m *AllocateIdsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_AllocateIdsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_AllocateIdsRequest proto.InternalMessageInfo - -func (m *AllocateIdsRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *AllocateIdsRequest) GetModelKey() *Reference { - if m != nil { - return m.ModelKey - } - return nil -} - -func (m *AllocateIdsRequest) GetSize() int64 { - if m != nil && m.Size != nil { - return *m.Size - } - return 0 -} - -func (m *AllocateIdsRequest) GetMax() int64 { - if m != nil && m.Max != nil { - return *m.Max - } - return 0 -} - -func (m *AllocateIdsRequest) GetReserve() []*Reference { - if m != nil { - return m.Reserve - } - return nil -} - -type AllocateIdsResponse struct { - Start *int64 `protobuf:"varint,1,req,name=start" json:"start,omitempty"` - End *int64 `protobuf:"varint,2,req,name=end" json:"end,omitempty"` - Cost *Cost `protobuf:"bytes,3,opt,name=cost" json:"cost,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AllocateIdsResponse) Reset() { *m = AllocateIdsResponse{} } -func (m *AllocateIdsResponse) String() string { return proto.CompactTextString(m) } -func (*AllocateIdsResponse) ProtoMessage() {} -func (*AllocateIdsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{32} -} -func (m *AllocateIdsResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AllocateIdsResponse.Unmarshal(m, b) -} -func (m *AllocateIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AllocateIdsResponse.Marshal(b, m, deterministic) -} -func (dst *AllocateIdsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllocateIdsResponse.Merge(dst, src) -} -func (m *AllocateIdsResponse) XXX_Size() int { - return xxx_messageInfo_AllocateIdsResponse.Size(m) -} -func (m *AllocateIdsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_AllocateIdsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_AllocateIdsResponse proto.InternalMessageInfo - -func (m *AllocateIdsResponse) GetStart() int64 { - if m != nil && m.Start != nil { - return *m.Start - } - return 0 -} - -func (m *AllocateIdsResponse) GetEnd() int64 { - if m != nil && m.End != nil { - return *m.End - } - return 0 -} - -func (m *AllocateIdsResponse) GetCost() *Cost { - if m != nil { - return m.Cost - } - return nil -} - -type CompositeIndices struct { - Index []*CompositeIndex `protobuf:"bytes,1,rep,name=index" json:"index,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CompositeIndices) Reset() { *m = CompositeIndices{} } -func (m *CompositeIndices) String() string { return proto.CompactTextString(m) } -func (*CompositeIndices) ProtoMessage() {} -func (*CompositeIndices) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{33} -} -func (m *CompositeIndices) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CompositeIndices.Unmarshal(m, b) -} -func (m *CompositeIndices) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CompositeIndices.Marshal(b, m, deterministic) -} -func (dst *CompositeIndices) XXX_Merge(src proto.Message) { - xxx_messageInfo_CompositeIndices.Merge(dst, src) -} -func (m *CompositeIndices) XXX_Size() int { - return xxx_messageInfo_CompositeIndices.Size(m) -} -func (m *CompositeIndices) XXX_DiscardUnknown() { - xxx_messageInfo_CompositeIndices.DiscardUnknown(m) -} - -var xxx_messageInfo_CompositeIndices proto.InternalMessageInfo - -func (m *CompositeIndices) GetIndex() []*CompositeIndex { - if m != nil { - return m.Index - } - return nil -} - -type AddActionsRequest struct { - Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"` - Transaction *Transaction `protobuf:"bytes,1,req,name=transaction" json:"transaction,omitempty"` - Action []*Action `protobuf:"bytes,2,rep,name=action" json:"action,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AddActionsRequest) Reset() { *m = AddActionsRequest{} } -func (m *AddActionsRequest) String() string { return proto.CompactTextString(m) } -func (*AddActionsRequest) ProtoMessage() {} -func (*AddActionsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{34} -} -func (m *AddActionsRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AddActionsRequest.Unmarshal(m, b) -} -func (m *AddActionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AddActionsRequest.Marshal(b, m, deterministic) -} -func (dst *AddActionsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddActionsRequest.Merge(dst, src) -} -func (m *AddActionsRequest) XXX_Size() int { - return xxx_messageInfo_AddActionsRequest.Size(m) -} -func (m *AddActionsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_AddActionsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_AddActionsRequest proto.InternalMessageInfo - -func (m *AddActionsRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *AddActionsRequest) GetTransaction() *Transaction { - if m != nil { - return m.Transaction - } - return nil -} - -func (m *AddActionsRequest) GetAction() []*Action { - if m != nil { - return m.Action - } - return nil -} - -type AddActionsResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AddActionsResponse) Reset() { *m = AddActionsResponse{} } -func (m *AddActionsResponse) String() string { return proto.CompactTextString(m) } -func (*AddActionsResponse) ProtoMessage() {} -func (*AddActionsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{35} -} -func (m *AddActionsResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AddActionsResponse.Unmarshal(m, b) -} -func (m *AddActionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AddActionsResponse.Marshal(b, m, deterministic) -} -func (dst *AddActionsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddActionsResponse.Merge(dst, src) -} -func (m *AddActionsResponse) XXX_Size() int { - return xxx_messageInfo_AddActionsResponse.Size(m) -} -func (m *AddActionsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_AddActionsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_AddActionsResponse proto.InternalMessageInfo - -type BeginTransactionRequest struct { - Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"` - App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"` - AllowMultipleEg *bool `protobuf:"varint,2,opt,name=allow_multiple_eg,json=allowMultipleEg,def=0" json:"allow_multiple_eg,omitempty"` - DatabaseId *string `protobuf:"bytes,4,opt,name=database_id,json=databaseId" json:"database_id,omitempty"` - Mode *BeginTransactionRequest_TransactionMode `protobuf:"varint,5,opt,name=mode,enum=appengine.BeginTransactionRequest_TransactionMode,def=0" json:"mode,omitempty"` - PreviousTransaction *Transaction `protobuf:"bytes,7,opt,name=previous_transaction,json=previousTransaction" json:"previous_transaction,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *BeginTransactionRequest) Reset() { *m = BeginTransactionRequest{} } -func (m *BeginTransactionRequest) String() string { return proto.CompactTextString(m) } -func (*BeginTransactionRequest) ProtoMessage() {} -func (*BeginTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36} -} -func (m *BeginTransactionRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BeginTransactionRequest.Unmarshal(m, b) -} -func (m *BeginTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BeginTransactionRequest.Marshal(b, m, deterministic) -} -func (dst *BeginTransactionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginTransactionRequest.Merge(dst, src) -} -func (m *BeginTransactionRequest) XXX_Size() int { - return xxx_messageInfo_BeginTransactionRequest.Size(m) -} -func (m *BeginTransactionRequest) XXX_DiscardUnknown() { - xxx_messageInfo_BeginTransactionRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_BeginTransactionRequest proto.InternalMessageInfo - -const Default_BeginTransactionRequest_AllowMultipleEg bool = false -const Default_BeginTransactionRequest_Mode BeginTransactionRequest_TransactionMode = BeginTransactionRequest_UNKNOWN - -func (m *BeginTransactionRequest) GetHeader() *InternalHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *BeginTransactionRequest) GetApp() string { - if m != nil && m.App != nil { - return *m.App - } - return "" -} - -func (m *BeginTransactionRequest) GetAllowMultipleEg() bool { - if m != nil && m.AllowMultipleEg != nil { - return *m.AllowMultipleEg - } - return Default_BeginTransactionRequest_AllowMultipleEg -} - -func (m *BeginTransactionRequest) GetDatabaseId() string { - if m != nil && m.DatabaseId != nil { - return *m.DatabaseId - } - return "" -} - -func (m *BeginTransactionRequest) GetMode() BeginTransactionRequest_TransactionMode { - if m != nil && m.Mode != nil { - return *m.Mode - } - return Default_BeginTransactionRequest_Mode -} - -func (m *BeginTransactionRequest) GetPreviousTransaction() *Transaction { - if m != nil { - return m.PreviousTransaction - } - return nil -} - -type CommitResponse struct { - Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"` - Version []*CommitResponse_Version `protobuf:"group,3,rep,name=Version,json=version" json:"version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CommitResponse) Reset() { *m = CommitResponse{} } -func (m *CommitResponse) String() string { return proto.CompactTextString(m) } -func (*CommitResponse) ProtoMessage() {} -func (*CommitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37} -} -func (m *CommitResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CommitResponse.Unmarshal(m, b) -} -func (m *CommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CommitResponse.Marshal(b, m, deterministic) -} -func (dst *CommitResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitResponse.Merge(dst, src) -} -func (m *CommitResponse) XXX_Size() int { - return xxx_messageInfo_CommitResponse.Size(m) -} -func (m *CommitResponse) XXX_DiscardUnknown() { - xxx_messageInfo_CommitResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_CommitResponse proto.InternalMessageInfo - -func (m *CommitResponse) GetCost() *Cost { - if m != nil { - return m.Cost - } - return nil -} - -func (m *CommitResponse) GetVersion() []*CommitResponse_Version { - if m != nil { - return m.Version - } - return nil -} - -type CommitResponse_Version struct { - RootEntityKey *Reference `protobuf:"bytes,4,req,name=root_entity_key,json=rootEntityKey" json:"root_entity_key,omitempty"` - Version *int64 `protobuf:"varint,5,req,name=version" json:"version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CommitResponse_Version) Reset() { *m = CommitResponse_Version{} } -func (m *CommitResponse_Version) String() string { return proto.CompactTextString(m) } -func (*CommitResponse_Version) ProtoMessage() {} -func (*CommitResponse_Version) Descriptor() ([]byte, []int) { - return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37, 0} -} -func (m *CommitResponse_Version) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CommitResponse_Version.Unmarshal(m, b) -} -func (m *CommitResponse_Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CommitResponse_Version.Marshal(b, m, deterministic) -} -func (dst *CommitResponse_Version) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitResponse_Version.Merge(dst, src) -} -func (m *CommitResponse_Version) XXX_Size() int { - return xxx_messageInfo_CommitResponse_Version.Size(m) -} -func (m *CommitResponse_Version) XXX_DiscardUnknown() { - xxx_messageInfo_CommitResponse_Version.DiscardUnknown(m) -} - -var xxx_messageInfo_CommitResponse_Version proto.InternalMessageInfo - -func (m *CommitResponse_Version) GetRootEntityKey() *Reference { - if m != nil { - return m.RootEntityKey - } - return nil -} - -func (m *CommitResponse_Version) GetVersion() int64 { - if m != nil && m.Version != nil { - return *m.Version - } - return 0 -} - -func init() { - proto.RegisterType((*Action)(nil), "appengine.Action") - proto.RegisterType((*PropertyValue)(nil), "appengine.PropertyValue") - proto.RegisterType((*PropertyValue_PointValue)(nil), "appengine.PropertyValue.PointValue") - proto.RegisterType((*PropertyValue_UserValue)(nil), "appengine.PropertyValue.UserValue") - proto.RegisterType((*PropertyValue_ReferenceValue)(nil), "appengine.PropertyValue.ReferenceValue") - proto.RegisterType((*PropertyValue_ReferenceValue_PathElement)(nil), "appengine.PropertyValue.ReferenceValue.PathElement") - proto.RegisterType((*Property)(nil), "appengine.Property") - proto.RegisterType((*Path)(nil), "appengine.Path") - proto.RegisterType((*Path_Element)(nil), "appengine.Path.Element") - proto.RegisterType((*Reference)(nil), "appengine.Reference") - proto.RegisterType((*User)(nil), "appengine.User") - proto.RegisterType((*EntityProto)(nil), "appengine.EntityProto") - proto.RegisterType((*CompositeProperty)(nil), "appengine.CompositeProperty") - proto.RegisterType((*Index)(nil), "appengine.Index") - proto.RegisterType((*Index_Property)(nil), "appengine.Index.Property") - proto.RegisterType((*CompositeIndex)(nil), "appengine.CompositeIndex") - proto.RegisterType((*IndexPostfix)(nil), "appengine.IndexPostfix") - proto.RegisterType((*IndexPostfix_IndexValue)(nil), "appengine.IndexPostfix.IndexValue") - proto.RegisterType((*IndexPosition)(nil), "appengine.IndexPosition") - proto.RegisterType((*Snapshot)(nil), "appengine.Snapshot") - proto.RegisterType((*InternalHeader)(nil), "appengine.InternalHeader") - proto.RegisterType((*Transaction)(nil), "appengine.Transaction") - proto.RegisterType((*Query)(nil), "appengine.Query") - proto.RegisterType((*Query_Filter)(nil), "appengine.Query.Filter") - proto.RegisterType((*Query_Order)(nil), "appengine.Query.Order") - proto.RegisterType((*CompiledQuery)(nil), "appengine.CompiledQuery") - proto.RegisterType((*CompiledQuery_PrimaryScan)(nil), "appengine.CompiledQuery.PrimaryScan") - proto.RegisterType((*CompiledQuery_MergeJoinScan)(nil), "appengine.CompiledQuery.MergeJoinScan") - proto.RegisterType((*CompiledQuery_EntityFilter)(nil), "appengine.CompiledQuery.EntityFilter") - proto.RegisterType((*CompiledCursor)(nil), "appengine.CompiledCursor") - proto.RegisterType((*CompiledCursor_Position)(nil), "appengine.CompiledCursor.Position") - proto.RegisterType((*CompiledCursor_Position_IndexValue)(nil), "appengine.CompiledCursor.Position.IndexValue") - proto.RegisterType((*Cursor)(nil), "appengine.Cursor") - proto.RegisterType((*Error)(nil), "appengine.Error") - proto.RegisterType((*Cost)(nil), "appengine.Cost") - proto.RegisterType((*Cost_CommitCost)(nil), "appengine.Cost.CommitCost") - proto.RegisterType((*GetRequest)(nil), "appengine.GetRequest") - proto.RegisterType((*GetResponse)(nil), "appengine.GetResponse") - proto.RegisterType((*GetResponse_Entity)(nil), "appengine.GetResponse.Entity") - proto.RegisterType((*PutRequest)(nil), "appengine.PutRequest") - proto.RegisterType((*PutResponse)(nil), "appengine.PutResponse") - proto.RegisterType((*TouchRequest)(nil), "appengine.TouchRequest") - proto.RegisterType((*TouchResponse)(nil), "appengine.TouchResponse") - proto.RegisterType((*DeleteRequest)(nil), "appengine.DeleteRequest") - proto.RegisterType((*DeleteResponse)(nil), "appengine.DeleteResponse") - proto.RegisterType((*NextRequest)(nil), "appengine.NextRequest") - proto.RegisterType((*QueryResult)(nil), "appengine.QueryResult") - proto.RegisterType((*AllocateIdsRequest)(nil), "appengine.AllocateIdsRequest") - proto.RegisterType((*AllocateIdsResponse)(nil), "appengine.AllocateIdsResponse") - proto.RegisterType((*CompositeIndices)(nil), "appengine.CompositeIndices") - proto.RegisterType((*AddActionsRequest)(nil), "appengine.AddActionsRequest") - proto.RegisterType((*AddActionsResponse)(nil), "appengine.AddActionsResponse") - proto.RegisterType((*BeginTransactionRequest)(nil), "appengine.BeginTransactionRequest") - proto.RegisterType((*CommitResponse)(nil), "appengine.CommitResponse") - proto.RegisterType((*CommitResponse_Version)(nil), "appengine.CommitResponse.Version") -} - -func init() { - proto.RegisterFile("google.golang.org/appengine/internal/datastore/datastore_v3.proto", fileDescriptor_datastore_v3_83b17b80c34f6179) -} - -var fileDescriptor_datastore_v3_83b17b80c34f6179 = []byte{ - // 4156 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0xe3, 0x46, - 0x76, 0x37, 0xc1, 0xef, 0x47, 0x89, 0x82, 0x5a, 0xf3, 0xc1, 0xa1, 0x3f, 0x46, 0xc6, 0xac, 0x6d, - 0xd9, 0x6b, 0x73, 0x6c, 0xf9, 0x23, 0x5b, 0x4a, 0x76, 0x1d, 0x4a, 0xc4, 0x68, 0x90, 0xa1, 0x48, - 0xb9, 0x09, 0xd9, 0x9e, 0x5c, 0x50, 0x18, 0xa2, 0x29, 0x21, 0x43, 0x02, 0x30, 0x00, 0x6a, 0x46, - 0x93, 0xe4, 0x90, 0x4b, 0x2a, 0x55, 0x5b, 0xa9, 0x1c, 0x92, 0x4a, 0x25, 0xf9, 0x07, 0x72, 0xc8, - 0x39, 0x95, 0xaa, 0x54, 0xf6, 0x98, 0x5b, 0x0e, 0x7b, 0xc9, 0x31, 0x95, 0x73, 0xf2, 0x27, 0x24, - 0x39, 0xa4, 0xfa, 0x75, 0x03, 0x02, 0x28, 0x4a, 0x23, 0x6d, 0xf6, 0x90, 0x13, 0xd1, 0xef, 0xfd, - 0xba, 0xf1, 0xfa, 0xf5, 0xfb, 0x6c, 0x10, 0xba, 0xc7, 0xbe, 0x7f, 0x3c, 0x65, 0x9d, 0x63, 0x7f, - 0x6a, 0x7b, 0xc7, 0x1d, 0x3f, 0x3c, 0x7e, 0x68, 0x07, 0x01, 0xf3, 0x8e, 0x5d, 0x8f, 0x3d, 0x74, - 0xbd, 0x98, 0x85, 0x9e, 0x3d, 0x7d, 0xe8, 0xd8, 0xb1, 0x1d, 0xc5, 0x7e, 0xc8, 0xce, 0x9f, 0xac, - 0xd3, 0xcf, 0x3b, 0x41, 0xe8, 0xc7, 0x3e, 0xa9, 0xa7, 0x13, 0xb4, 0x1a, 0x54, 0xba, 0xe3, 0xd8, - 0xf5, 0x3d, 0xed, 0x1f, 0x2b, 0xb0, 0x7a, 0x18, 0xfa, 0x01, 0x0b, 0xe3, 0xb3, 0x6f, 0xed, 0xe9, - 0x9c, 0x91, 0x77, 0x00, 0x5c, 0x2f, 0xfe, 0xea, 0x0b, 0x1c, 0xb5, 0x0a, 0x9b, 0x85, 0xad, 0x22, - 0xcd, 0x50, 0x88, 0x06, 0x2b, 0xcf, 0x7c, 0x7f, 0xca, 0x6c, 0x4f, 0x20, 0x94, 0xcd, 0xc2, 0x56, - 0x8d, 0xe6, 0x68, 0x64, 0x13, 0x1a, 0x51, 0x1c, 0xba, 0xde, 0xb1, 0x80, 0x14, 0x37, 0x0b, 0x5b, - 0x75, 0x9a, 0x25, 0x71, 0x84, 0xe3, 0xcf, 0x9f, 0x4d, 0x99, 0x40, 0x94, 0x36, 0x0b, 0x5b, 0x05, - 0x9a, 0x25, 0x91, 0x3d, 0x80, 0xc0, 0x77, 0xbd, 0xf8, 0x14, 0x01, 0xe5, 0xcd, 0xc2, 0x16, 0x6c, - 0x3f, 0xe8, 0xa4, 0x7b, 0xe8, 0xe4, 0xa4, 0xee, 0x1c, 0x72, 0x28, 0x3e, 0xd2, 0xcc, 0x34, 0xf2, - 0xdb, 0x50, 0x9f, 0x47, 0x2c, 0x14, 0x6b, 0xd4, 0x70, 0x0d, 0xed, 0xd2, 0x35, 0x8e, 0x22, 0x16, - 0x8a, 0x25, 0xce, 0x27, 0x91, 0x21, 0x34, 0x43, 0x36, 0x61, 0x21, 0xf3, 0xc6, 0x4c, 0x2c, 0xb3, - 0x82, 0xcb, 0x7c, 0x70, 0xe9, 0x32, 0x34, 0x81, 0x8b, 0xb5, 0x16, 0xa6, 0xb7, 0xb7, 0x00, 0xce, - 0x85, 0x25, 0x2b, 0x50, 0x78, 0xd9, 0xaa, 0x6c, 0x2a, 0x5b, 0x05, 0x5a, 0x78, 0xc9, 0x47, 0x67, - 0xad, 0xaa, 0x18, 0x9d, 0xb5, 0xff, 0xa9, 0x00, 0xf5, 0x54, 0x26, 0x72, 0x0b, 0xca, 0x6c, 0x66, - 0xbb, 0xd3, 0x56, 0x7d, 0x53, 0xd9, 0xaa, 0x53, 0x31, 0x20, 0xf7, 0xa1, 0x61, 0xcf, 0xe3, 0x13, - 0xcb, 0xf1, 0x67, 0xb6, 0xeb, 0xb5, 0x00, 0x79, 0xc0, 0x49, 0x3d, 0xa4, 0x90, 0x36, 0xd4, 0x3c, - 0x77, 0xfc, 0xdc, 0xb3, 0x67, 0xac, 0xd5, 0xc0, 0x73, 0x48, 0xc7, 0xe4, 0x13, 0x20, 0x13, 0xe6, - 0xb0, 0xd0, 0x8e, 0x99, 0x63, 0xb9, 0x0e, 0xf3, 0x62, 0x37, 0x3e, 0x6b, 0xdd, 0x46, 0xd4, 0x7a, - 0xca, 0x31, 0x24, 0x23, 0x0f, 0x0f, 0x42, 0xff, 0xd4, 0x75, 0x58, 0xd8, 0xba, 0xb3, 0x00, 0x3f, - 0x94, 0x8c, 0xf6, 0xbf, 0x17, 0xa0, 0x99, 0xd7, 0x05, 0x51, 0xa1, 0x68, 0x07, 0x41, 0x6b, 0x15, - 0xa5, 0xe4, 0x8f, 0xe4, 0x6d, 0x00, 0x2e, 0x8a, 0x15, 0x05, 0xf6, 0x98, 0xb5, 0x6e, 0xe1, 0x5a, - 0x75, 0x4e, 0x19, 0x71, 0x02, 0x39, 0x82, 0x46, 0x60, 0xc7, 0x27, 0x6c, 0xca, 0x66, 0xcc, 0x8b, - 0x5b, 0xcd, 0xcd, 0xe2, 0x16, 0x6c, 0x7f, 0x7e, 0x4d, 0xd5, 0x77, 0x0e, 0xed, 0xf8, 0x44, 0x17, - 0x53, 0x69, 0x76, 0x9d, 0xb6, 0x0e, 0x8d, 0x0c, 0x8f, 0x10, 0x28, 0xc5, 0x67, 0x01, 0x6b, 0xad, - 0xa1, 0x5c, 0xf8, 0x4c, 0x9a, 0xa0, 0xb8, 0x4e, 0x4b, 0x45, 0xf3, 0x57, 0x5c, 0x87, 0x63, 0x50, - 0x87, 0xeb, 0x28, 0x22, 0x3e, 0x6b, 0xff, 0x51, 0x86, 0x5a, 0x22, 0x00, 0xe9, 0x42, 0x75, 0xc6, - 0x6c, 0xcf, 0xf5, 0x8e, 0xd1, 0x69, 0x9a, 0xdb, 0x6f, 0x2e, 0x11, 0xb3, 0x73, 0x20, 0x20, 0x3b, - 0x30, 0x18, 0x5a, 0x07, 0x7a, 0x77, 0x60, 0x0c, 0xf6, 0x69, 0x32, 0x8f, 0x1f, 0xa6, 0x7c, 0xb4, - 0xe6, 0xa1, 0x8b, 0x9e, 0x55, 0xa7, 0x20, 0x49, 0x47, 0xa1, 0x9b, 0x0a, 0x51, 0x14, 0x82, 0xe2, - 0x21, 0x76, 0xa0, 0x9c, 0xb8, 0x88, 0xb2, 0xd5, 0xd8, 0x6e, 0x5d, 0xa6, 0x1c, 0x2a, 0x60, 0xdc, - 0x20, 0x66, 0xf3, 0x69, 0xec, 0x06, 0x53, 0xee, 0x76, 0xca, 0x56, 0x8d, 0xa6, 0x63, 0xf2, 0x1e, - 0x40, 0xc4, 0xec, 0x70, 0x7c, 0x62, 0x3f, 0x9b, 0xb2, 0x56, 0x85, 0x7b, 0xf6, 0x4e, 0x79, 0x62, - 0x4f, 0x23, 0x46, 0x33, 0x0c, 0x62, 0xc3, 0xdd, 0x49, 0x1c, 0x59, 0xb1, 0xff, 0x9c, 0x79, 0xee, - 0x2b, 0x9b, 0x07, 0x12, 0xcb, 0x0f, 0xf8, 0x0f, 0xfa, 0x58, 0x73, 0xfb, 0xc3, 0x65, 0x5b, 0x7f, - 0x14, 0x47, 0x66, 0x66, 0xc6, 0x10, 0x27, 0xd0, 0xdb, 0x93, 0x65, 0x64, 0xd2, 0x86, 0xca, 0xd4, - 0x1f, 0xdb, 0x53, 0xd6, 0xaa, 0x73, 0x2d, 0xec, 0x28, 0xcc, 0xa3, 0x92, 0xa2, 0xfd, 0xb3, 0x02, - 0x55, 0xa9, 0x47, 0xd2, 0x84, 0x8c, 0x26, 0xd5, 0x37, 0x48, 0x0d, 0x4a, 0xbb, 0xfd, 0xe1, 0xae, - 0xda, 0xe4, 0x4f, 0xa6, 0xfe, 0xbd, 0xa9, 0xae, 0x71, 0xcc, 0xee, 0x53, 0x53, 0x1f, 0x99, 0x94, - 0x63, 0x54, 0xb2, 0x0e, 0xab, 0x5d, 0x73, 0x78, 0x60, 0xed, 0x75, 0x4d, 0x7d, 0x7f, 0x48, 0x9f, - 0xaa, 0x05, 0xb2, 0x0a, 0x75, 0x24, 0xf5, 0x8d, 0xc1, 0x13, 0x55, 0xe1, 0x33, 0x70, 0x68, 0x1a, - 0x66, 0x5f, 0x57, 0x8b, 0x44, 0x85, 0x15, 0x31, 0x63, 0x38, 0x30, 0xf5, 0x81, 0xa9, 0x96, 0x52, - 0xca, 0xe8, 0xe8, 0xe0, 0xa0, 0x4b, 0x9f, 0xaa, 0x65, 0xb2, 0x06, 0x0d, 0xa4, 0x74, 0x8f, 0xcc, - 0xc7, 0x43, 0xaa, 0x56, 0x48, 0x03, 0xaa, 0xfb, 0x3d, 0xeb, 0xbb, 0xc7, 0xfa, 0x40, 0xad, 0x92, - 0x15, 0xa8, 0xed, 0xf7, 0x2c, 0xfd, 0xa0, 0x6b, 0xf4, 0xd5, 0x1a, 0x9f, 0xbd, 0xaf, 0x0f, 0xe9, - 0x68, 0x64, 0x1d, 0x0e, 0x8d, 0x81, 0xa9, 0xd6, 0x49, 0x1d, 0xca, 0xfb, 0x3d, 0xcb, 0x38, 0x50, - 0x81, 0x10, 0x68, 0xee, 0xf7, 0xac, 0xc3, 0xc7, 0xc3, 0x81, 0x3e, 0x38, 0x3a, 0xd8, 0xd5, 0xa9, - 0xda, 0x20, 0xb7, 0x40, 0xe5, 0xb4, 0xe1, 0xc8, 0xec, 0xf6, 0xbb, 0xbd, 0x1e, 0xd5, 0x47, 0x23, - 0x75, 0x85, 0x4b, 0xbd, 0xdf, 0xb3, 0x68, 0xd7, 0xe4, 0xfb, 0x5a, 0xe5, 0x2f, 0xe4, 0x7b, 0x7f, - 0xa2, 0x3f, 0x55, 0xd7, 0xf9, 0x2b, 0xf4, 0x81, 0x69, 0x98, 0x4f, 0xad, 0x43, 0x3a, 0x34, 0x87, - 0xea, 0x06, 0x17, 0xd0, 0x18, 0xf4, 0xf4, 0xef, 0xad, 0x6f, 0xbb, 0xfd, 0x23, 0x5d, 0x25, 0xda, - 0x8f, 0xe1, 0xf6, 0xd2, 0x33, 0xe1, 0xaa, 0x7b, 0x6c, 0x1e, 0xf4, 0xd5, 0x02, 0x7f, 0xe2, 0x9b, - 0x52, 0x15, 0xed, 0x0f, 0xa0, 0xc4, 0x5d, 0x86, 0x7c, 0x06, 0xd5, 0xc4, 0x1b, 0x0b, 0xe8, 0x8d, - 0x77, 0xb3, 0x67, 0x6d, 0xc7, 0x27, 0x9d, 0xc4, 0xe3, 0x12, 0x5c, 0xbb, 0x0b, 0xd5, 0x45, 0x4f, - 0x53, 0x2e, 0x78, 0x5a, 0xf1, 0x82, 0xa7, 0x95, 0x32, 0x9e, 0x66, 0x43, 0x3d, 0xf5, 0xed, 0x9b, - 0x47, 0x91, 0x07, 0x50, 0xe2, 0xde, 0xdf, 0x6a, 0xa2, 0x87, 0xac, 0x2d, 0x08, 0x4c, 0x91, 0xa9, - 0xfd, 0x43, 0x01, 0x4a, 0x3c, 0xda, 0x9e, 0x07, 0xda, 0xc2, 0x15, 0x81, 0x56, 0xb9, 0x32, 0xd0, - 0x16, 0xaf, 0x15, 0x68, 0x2b, 0x37, 0x0b, 0xb4, 0xd5, 0x4b, 0x02, 0xad, 0xf6, 0x67, 0x45, 0x68, - 0xe8, 0x38, 0xf3, 0x10, 0x13, 0xfd, 0xfb, 0x50, 0x7c, 0xce, 0xce, 0x50, 0x3f, 0x8d, 0xed, 0x5b, - 0x99, 0xdd, 0xa6, 0x2a, 0xa4, 0x1c, 0x40, 0xb6, 0x61, 0x45, 0xbc, 0xd0, 0x3a, 0x0e, 0xfd, 0x79, - 0xd0, 0x52, 0x97, 0xab, 0xa7, 0x21, 0x40, 0xfb, 0x1c, 0x43, 0xde, 0x83, 0xb2, 0xff, 0xc2, 0x63, - 0x21, 0xc6, 0xc1, 0x3c, 0x98, 0x2b, 0x8f, 0x0a, 0x2e, 0x79, 0x08, 0xa5, 0xe7, 0xae, 0xe7, 0xe0, - 0x19, 0xe6, 0x23, 0x61, 0x46, 0xd0, 0xce, 0x13, 0xd7, 0x73, 0x28, 0x02, 0xc9, 0x3d, 0xa8, 0xf1, - 0x5f, 0x8c, 0x7b, 0x65, 0xdc, 0x68, 0x95, 0x8f, 0x79, 0xd0, 0x7b, 0x08, 0xb5, 0x40, 0xc6, 0x10, - 0x4c, 0x00, 0x8d, 0xed, 0x8d, 0x25, 0xe1, 0x85, 0xa6, 0x20, 0xf2, 0x15, 0xac, 0x84, 0xf6, 0x0b, - 0x2b, 0x9d, 0xb4, 0x76, 0xf9, 0xa4, 0x46, 0x68, 0xbf, 0x48, 0x23, 0x38, 0x81, 0x52, 0x68, 0x7b, - 0xcf, 0x5b, 0x64, 0xb3, 0xb0, 0x55, 0xa6, 0xf8, 0xac, 0x7d, 0x01, 0x25, 0x2e, 0x25, 0x8f, 0x08, - 0xfb, 0x3d, 0xf4, 0xff, 0xee, 0x9e, 0xa9, 0x16, 0x12, 0x7f, 0xfe, 0x96, 0x47, 0x03, 0x45, 0x72, - 0x0f, 0xf4, 0xd1, 0xa8, 0xbb, 0xaf, 0xab, 0x45, 0xad, 0x07, 0xeb, 0x7b, 0xfe, 0x2c, 0xf0, 0x23, - 0x37, 0x66, 0xe9, 0xf2, 0xf7, 0xa0, 0xe6, 0x7a, 0x0e, 0x7b, 0x69, 0xb9, 0x0e, 0x9a, 0x56, 0x91, - 0x56, 0x71, 0x6c, 0x38, 0xdc, 0xe4, 0x4e, 0x65, 0x31, 0x55, 0xe4, 0x26, 0x87, 0x03, 0xed, 0x2f, - 0x15, 0x28, 0x1b, 0x1c, 0xc1, 0x8d, 0x4f, 0x9e, 0x14, 0x7a, 0x8f, 0x30, 0x4c, 0x10, 0x24, 0x93, - 0xfb, 0x50, 0x1b, 0x6a, 0xb6, 0x37, 0x66, 0xbc, 0xe2, 0xc3, 0x3c, 0x50, 0xa3, 0xe9, 0x98, 0x7c, - 0x99, 0xd1, 0x9f, 0x82, 0x2e, 0x7b, 0x2f, 0xa3, 0x0a, 0x7c, 0xc1, 0x12, 0x2d, 0xb6, 0xff, 0xaa, - 0x90, 0x49, 0x6e, 0xcb, 0x12, 0x4f, 0x1f, 0xea, 0x8e, 0x1b, 0x32, 0xac, 0x23, 0xe5, 0x41, 0x3f, - 0xb8, 0x74, 0xe1, 0x4e, 0x2f, 0x81, 0xee, 0xd4, 0xbb, 0xa3, 0x3d, 0x7d, 0xd0, 0xe3, 0x99, 0xef, - 0x7c, 0x01, 0xed, 0x23, 0xa8, 0xa7, 0x10, 0x0c, 0xc7, 0x09, 0x48, 0x2d, 0x70, 0xf5, 0xf6, 0xf4, - 0x74, 0xac, 0x68, 0x7f, 0xad, 0x40, 0x33, 0xd5, 0xaf, 0xd0, 0xd0, 0x6d, 0xa8, 0xd8, 0x41, 0x90, - 0xa8, 0xb6, 0x4e, 0xcb, 0x76, 0x10, 0x18, 0x8e, 0x8c, 0x2d, 0x0a, 0x6a, 0x9b, 0xc7, 0x96, 0x4f, - 0x01, 0x1c, 0x36, 0x71, 0x3d, 0x17, 0x85, 0x2e, 0xa2, 0xc1, 0xab, 0x8b, 0x42, 0xd3, 0x0c, 0x86, - 0x7c, 0x09, 0xe5, 0x28, 0xb6, 0x63, 0x91, 0x2b, 0x9b, 0xdb, 0xf7, 0x33, 0xe0, 0xbc, 0x08, 0x9d, - 0x11, 0x87, 0x51, 0x81, 0x26, 0x5f, 0xc1, 0x2d, 0xdf, 0x9b, 0x9e, 0x59, 0xf3, 0x88, 0x59, 0xee, - 0xc4, 0x0a, 0xd9, 0x0f, 0x73, 0x37, 0x64, 0x4e, 0x3e, 0xa7, 0xae, 0x73, 0xc8, 0x51, 0xc4, 0x8c, - 0x09, 0x95, 0x7c, 0xed, 0x6b, 0x28, 0xe3, 0x3a, 0x7c, 0xcf, 0xdf, 0x51, 0xc3, 0xd4, 0xad, 0xe1, - 0xa0, 0xff, 0x54, 0xe8, 0x80, 0xea, 0xdd, 0x9e, 0x85, 0x44, 0x55, 0xe1, 0xc1, 0xbe, 0xa7, 0xf7, - 0x75, 0x53, 0xef, 0xa9, 0x45, 0x9e, 0x3d, 0x74, 0x4a, 0x87, 0x54, 0x2d, 0x69, 0xff, 0x53, 0x80, - 0x15, 0x94, 0xe7, 0xd0, 0x8f, 0xe2, 0x89, 0xfb, 0x92, 0xec, 0x41, 0x43, 0x98, 0xdd, 0xa9, 0x2c, - 0xe8, 0xb9, 0x33, 0x68, 0x8b, 0x7b, 0x96, 0x68, 0x31, 0x90, 0x75, 0xb4, 0x9b, 0x3e, 0x27, 0x21, - 0x45, 0x41, 0xa7, 0xbf, 0x22, 0xa4, 0xbc, 0x05, 0x95, 0x67, 0x6c, 0xe2, 0x87, 0x22, 0x04, 0xd6, - 0x76, 0x4a, 0x71, 0x38, 0x67, 0x54, 0xd2, 0xda, 0x36, 0xc0, 0xf9, 0xfa, 0xe4, 0x01, 0xac, 0x26, - 0xc6, 0x66, 0xa1, 0x71, 0x89, 0x93, 0x5b, 0x49, 0x88, 0x83, 0x5c, 0x75, 0xa3, 0x5c, 0xab, 0xba, - 0xd1, 0xbe, 0x86, 0xd5, 0x64, 0x3f, 0xe2, 0xfc, 0x54, 0x21, 0x79, 0x01, 0x63, 0xca, 0x82, 0x8c, - 0xca, 0x45, 0x19, 0xb5, 0x9f, 0x41, 0x6d, 0xe4, 0xd9, 0x41, 0x74, 0xe2, 0xc7, 0xdc, 0x7a, 0xe2, - 0x48, 0xfa, 0xaa, 0x12, 0x47, 0x9a, 0x06, 0x15, 0x7e, 0x38, 0xf3, 0x88, 0xbb, 0xbf, 0x31, 0xe8, - 0xee, 0x99, 0xc6, 0xb7, 0xba, 0xfa, 0x06, 0x01, 0xa8, 0xc8, 0xe7, 0x82, 0xa6, 0x41, 0xd3, 0x90, - 0xed, 0xd8, 0x63, 0x66, 0x3b, 0x2c, 0xe4, 0x12, 0xfc, 0xe0, 0x47, 0x89, 0x04, 0x3f, 0xf8, 0x91, - 0xf6, 0x17, 0x05, 0x68, 0x98, 0xa1, 0xed, 0x45, 0xb6, 0x30, 0xf7, 0xcf, 0xa0, 0x72, 0x82, 0x58, - 0x74, 0xa3, 0xc6, 0x82, 0x7f, 0x66, 0x17, 0xa3, 0x12, 0x48, 0xee, 0x40, 0xe5, 0xc4, 0xf6, 0x9c, - 0xa9, 0xd0, 0x5a, 0x85, 0xca, 0x51, 0x92, 0x1b, 0x95, 0xf3, 0xdc, 0xb8, 0x05, 0x2b, 0x33, 0x3b, - 0x7c, 0x6e, 0x8d, 0x4f, 0x6c, 0xef, 0x98, 0x45, 0xf2, 0x60, 0xa4, 0x05, 0x36, 0x38, 0x6b, 0x4f, - 0x70, 0xb4, 0xbf, 0x5f, 0x81, 0xf2, 0x37, 0x73, 0x16, 0x9e, 0x65, 0x04, 0xfa, 0xe0, 0xba, 0x02, - 0xc9, 0x17, 0x17, 0x2e, 0x4b, 0xca, 0x6f, 0x2f, 0x26, 0x65, 0x22, 0x53, 0x84, 0xc8, 0x95, 0x22, - 0x0b, 0x7c, 0x9a, 0x09, 0x63, 0xeb, 0x57, 0xd8, 0xda, 0x79, 0x70, 0x7b, 0x08, 0x95, 0x89, 0x3b, - 0x8d, 0x51, 0x75, 0x8b, 0xd5, 0x08, 0xee, 0xa5, 0xf3, 0x08, 0xd9, 0x54, 0xc2, 0xc8, 0xbb, 0xb0, - 0x22, 0x2a, 0x59, 0xeb, 0x07, 0xce, 0xc6, 0x82, 0x95, 0xf7, 0xa6, 0x48, 0x13, 0xbb, 0xff, 0x18, - 0xca, 0x7e, 0xc8, 0x37, 0x5f, 0xc7, 0x25, 0xef, 0x5c, 0x58, 0x72, 0xc8, 0xb9, 0x54, 0x80, 0xc8, - 0x87, 0x50, 0x3a, 0x71, 0xbd, 0x18, 0xb3, 0x46, 0x73, 0xfb, 0xf6, 0x05, 0xf0, 0x63, 0xd7, 0x8b, - 0x29, 0x42, 0x78, 0x98, 0x1f, 0xfb, 0x73, 0x2f, 0x6e, 0xdd, 0xc5, 0x0c, 0x23, 0x06, 0xe4, 0x1e, - 0x54, 0xfc, 0xc9, 0x24, 0x62, 0x31, 0x76, 0x96, 0xe5, 0x9d, 0xc2, 0xa7, 0x54, 0x12, 0xf8, 0x84, - 0xa9, 0x3b, 0x73, 0x63, 0xec, 0x43, 0xca, 0x54, 0x0c, 0xc8, 0x2e, 0xac, 0x8d, 0xfd, 0x59, 0xe0, - 0x4e, 0x99, 0x63, 0x8d, 0xe7, 0x61, 0xe4, 0x87, 0xad, 0x77, 0x2e, 0x1c, 0xd3, 0x9e, 0x44, 0xec, - 0x21, 0x80, 0x36, 0xc7, 0xb9, 0x31, 0x31, 0x60, 0x83, 0x79, 0x8e, 0xb5, 0xb8, 0xce, 0xfd, 0xd7, - 0xad, 0xb3, 0xce, 0x3c, 0x27, 0x4f, 0x4a, 0xc4, 0xc1, 0x48, 0x68, 0x61, 0xcc, 0x68, 0x6d, 0x60, - 0x90, 0xb9, 0x77, 0x69, 0xac, 0x14, 0xe2, 0x64, 0xc2, 0xf7, 0x6f, 0xc0, 0x2d, 0x19, 0x22, 0xad, - 0x80, 0x85, 0x13, 0x36, 0x8e, 0xad, 0x60, 0x6a, 0x7b, 0x58, 0xca, 0xa5, 0xc6, 0x4a, 0x24, 0xe4, - 0x50, 0x20, 0x0e, 0xa7, 0xb6, 0x47, 0x34, 0xa8, 0x3f, 0x67, 0x67, 0x91, 0xc5, 0x23, 0x29, 0x76, - 0xae, 0x29, 0xba, 0xc6, 0xe9, 0x43, 0x6f, 0x7a, 0x46, 0x7e, 0x02, 0x8d, 0xf8, 0xdc, 0xdb, 0xb0, - 0x61, 0x6d, 0xe4, 0x4e, 0x35, 0xe3, 0x8b, 0x34, 0x0b, 0x25, 0xf7, 0xa1, 0x2a, 0x35, 0xd4, 0xba, - 0x97, 0x5d, 0x3b, 0xa1, 0xf2, 0xc4, 0x3c, 0xb1, 0xdd, 0xa9, 0x7f, 0xca, 0x42, 0x6b, 0x16, 0xb5, - 0xda, 0xe2, 0xb6, 0x24, 0x21, 0x1d, 0x44, 0xdc, 0x4f, 0xa3, 0x38, 0xf4, 0xbd, 0xe3, 0xd6, 0x26, - 0xde, 0x93, 0xc8, 0xd1, 0xc5, 0xe0, 0xf7, 0x2e, 0x66, 0xfe, 0x7c, 0xf0, 0xfb, 0x1c, 0xee, 0x60, - 0x65, 0x66, 0x3d, 0x3b, 0xb3, 0xf2, 0x68, 0x0d, 0xd1, 0x1b, 0xc8, 0xdd, 0x3d, 0x3b, 0xcc, 0x4e, - 0x6a, 0x43, 0xcd, 0x71, 0xa3, 0xd8, 0xf5, 0xc6, 0x71, 0xab, 0x85, 0xef, 0x4c, 0xc7, 0xe4, 0x33, - 0xb8, 0x3d, 0x73, 0x3d, 0x2b, 0xb2, 0x27, 0xcc, 0x8a, 0x5d, 0xee, 0x9b, 0x6c, 0xec, 0x7b, 0x4e, - 0xd4, 0x7a, 0x80, 0x82, 0x93, 0x99, 0xeb, 0x8d, 0xec, 0x09, 0x33, 0xdd, 0x19, 0x1b, 0x09, 0x0e, - 0xf9, 0x08, 0xd6, 0x11, 0x1e, 0xb2, 0x60, 0xea, 0x8e, 0x6d, 0xf1, 0xfa, 0x1f, 0xe1, 0xeb, 0xd7, - 0x38, 0x83, 0x0a, 0x3a, 0xbe, 0xfa, 0x63, 0x68, 0x06, 0x2c, 0x8c, 0xdc, 0x28, 0xb6, 0xa4, 0x45, - 0xbf, 0x97, 0xd5, 0xda, 0xaa, 0x64, 0x0e, 0x91, 0xd7, 0xfe, 0xcf, 0x02, 0x54, 0x84, 0x73, 0x92, - 0x4f, 0x41, 0xf1, 0x03, 0xbc, 0x06, 0x69, 0x6e, 0x6f, 0x5e, 0xe2, 0xc1, 0x9d, 0x61, 0xc0, 0xeb, - 0x5e, 0x3f, 0xa4, 0x8a, 0x1f, 0xdc, 0xb8, 0x28, 0xd4, 0xfe, 0x10, 0x6a, 0xc9, 0x02, 0xbc, 0xbc, - 0xe8, 0xeb, 0xa3, 0x91, 0x65, 0x3e, 0xee, 0x0e, 0xd4, 0x02, 0xb9, 0x03, 0x24, 0x1d, 0x5a, 0x43, - 0x6a, 0xe9, 0xdf, 0x1c, 0x75, 0xfb, 0xaa, 0x82, 0x5d, 0x1a, 0xd5, 0xbb, 0xa6, 0x4e, 0x05, 0xb2, - 0x48, 0xee, 0xc1, 0xed, 0x2c, 0xe5, 0x1c, 0x5c, 0xc2, 0x14, 0x8c, 0x8f, 0x65, 0x52, 0x01, 0xc5, - 0x18, 0xa8, 0x15, 0x9e, 0x16, 0xf4, 0xef, 0x8d, 0x91, 0x39, 0x52, 0xab, 0xed, 0xbf, 0x29, 0x40, - 0x19, 0xc3, 0x06, 0x3f, 0x9f, 0x54, 0x72, 0x71, 0x5d, 0x73, 0x5e, 0xb9, 0x1a, 0xd9, 0x92, 0xaa, - 0x81, 0x01, 0x65, 0x73, 0x79, 0xf4, 0xf9, 0xb5, 0xd6, 0x53, 0x3f, 0x85, 0x12, 0x8f, 0x52, 0xbc, - 0x43, 0x1c, 0xd2, 0x9e, 0x4e, 0xad, 0x47, 0x06, 0x1d, 0xf1, 0x2a, 0x97, 0x40, 0xb3, 0x3b, 0xd8, - 0xd3, 0x47, 0xe6, 0x30, 0xa1, 0xa1, 0x56, 0x1e, 0x19, 0x7d, 0x33, 0x45, 0x15, 0xb5, 0x9f, 0xd7, - 0x60, 0x35, 0x89, 0x09, 0x22, 0x82, 0x3e, 0x82, 0x46, 0x10, 0xba, 0x33, 0x3b, 0x3c, 0x8b, 0xc6, - 0xb6, 0x87, 0x49, 0x01, 0xb6, 0x7f, 0xb4, 0x24, 0xaa, 0x88, 0x1d, 0x1d, 0x0a, 0xec, 0x68, 0x6c, - 0x7b, 0x34, 0x3b, 0x91, 0xf4, 0x61, 0x75, 0xc6, 0xc2, 0x63, 0xf6, 0x7b, 0xbe, 0xeb, 0xe1, 0x4a, - 0x55, 0x8c, 0xc8, 0xef, 0x5f, 0xba, 0xd2, 0x01, 0x47, 0xff, 0x8e, 0xef, 0x7a, 0xb8, 0x56, 0x7e, - 0x32, 0xf9, 0x04, 0xea, 0xa2, 0x12, 0x72, 0xd8, 0x04, 0x63, 0xc5, 0xb2, 0xda, 0x4f, 0xd4, 0xe8, - 0x3d, 0x36, 0xc9, 0xc4, 0x65, 0xb8, 0x34, 0x2e, 0x37, 0xb2, 0x71, 0xf9, 0xcd, 0x6c, 0x2c, 0x5a, - 0x11, 0x55, 0x78, 0x1a, 0x84, 0x2e, 0x38, 0x7c, 0x6b, 0x89, 0xc3, 0x77, 0x60, 0x23, 0xf1, 0x55, - 0xcb, 0xf5, 0x26, 0xee, 0x4b, 0x2b, 0x72, 0x5f, 0x89, 0xd8, 0x53, 0xa6, 0xeb, 0x09, 0xcb, 0xe0, - 0x9c, 0x91, 0xfb, 0x8a, 0x11, 0x23, 0xe9, 0xe0, 0x64, 0x0e, 0x5c, 0xc5, 0xab, 0xc9, 0xf7, 0x2e, - 0x55, 0x8f, 0x68, 0xbe, 0x64, 0x46, 0xcc, 0x4d, 0x6d, 0xff, 0x52, 0x81, 0x46, 0xe6, 0x1c, 0x78, - 0xf6, 0x16, 0xca, 0x42, 0x61, 0xc5, 0x55, 0x94, 0x50, 0x1f, 0x4a, 0xfa, 0x26, 0xd4, 0xa3, 0xd8, - 0x0e, 0x63, 0x8b, 0x17, 0x57, 0xb2, 0xdd, 0x45, 0xc2, 0x13, 0x76, 0x46, 0x3e, 0x80, 0x35, 0xc1, - 0x74, 0xbd, 0xf1, 0x74, 0x1e, 0xb9, 0xa7, 0xa2, 0x99, 0xaf, 0xd1, 0x26, 0x92, 0x8d, 0x84, 0x4a, - 0xee, 0x42, 0x95, 0x67, 0x21, 0xbe, 0x86, 0x68, 0xfa, 0x2a, 0xcc, 0x73, 0xf8, 0x0a, 0x0f, 0x60, - 0x95, 0x33, 0xce, 0xe7, 0x57, 0xc4, 0x2d, 0x33, 0xf3, 0x9c, 0xf3, 0xd9, 0x1d, 0xd8, 0x10, 0xaf, - 0x09, 0x44, 0xf1, 0x2a, 0x2b, 0xdc, 0x3b, 0xa8, 0xd8, 0x75, 0x64, 0xc9, 0xb2, 0x56, 0x14, 0x9c, - 0x1f, 0x01, 0xcf, 0x5e, 0x0b, 0xe8, 0xbb, 0x22, 0x94, 0x31, 0xcf, 0xc9, 0x61, 0x77, 0xe1, 0x1d, - 0x8e, 0x9d, 0x7b, 0x76, 0x10, 0x4c, 0x5d, 0xe6, 0x58, 0x53, 0xff, 0x18, 0x43, 0x66, 0x14, 0xdb, - 0xb3, 0xc0, 0x9a, 0x47, 0xad, 0x0d, 0x0c, 0x99, 0x6d, 0xe6, 0x39, 0x47, 0x09, 0xa8, 0xef, 0x1f, - 0x9b, 0x09, 0xe4, 0x28, 0x6a, 0xff, 0x3e, 0xac, 0xe6, 0xec, 0x71, 0x41, 0xa7, 0x35, 0x74, 0xfe, - 0x8c, 0x4e, 0xdf, 0x85, 0x95, 0x20, 0x64, 0xe7, 0xa2, 0xd5, 0x51, 0xb4, 0x86, 0xa0, 0x09, 0xb1, - 0xb6, 0x60, 0x05, 0x79, 0x96, 0x20, 0xe6, 0xf3, 0x63, 0x03, 0x59, 0x87, 0xc8, 0x69, 0xbf, 0x80, - 0x95, 0xec, 0x69, 0x93, 0x77, 0x33, 0x69, 0xa1, 0x99, 0xcb, 0x93, 0x69, 0x76, 0x48, 0x2a, 0xb2, - 0xf5, 0x4b, 0x2a, 0x32, 0x72, 0x9d, 0x8a, 0x4c, 0xfb, 0x2f, 0xd9, 0x9c, 0x65, 0x2a, 0x84, 0x9f, - 0x41, 0x2d, 0x90, 0xf5, 0x38, 0x5a, 0x52, 0xfe, 0x12, 0x3e, 0x0f, 0xee, 0x24, 0x95, 0x3b, 0x4d, - 0xe7, 0xb4, 0xff, 0x56, 0x81, 0x5a, 0x5a, 0xd0, 0xe7, 0x2c, 0xef, 0xcd, 0x05, 0xcb, 0x3b, 0x90, - 0x1a, 0x16, 0x0a, 0x7c, 0x1b, 0xa3, 0xc5, 0x27, 0xaf, 0x7f, 0xd7, 0xc5, 0xb6, 0xe7, 0x34, 0xdb, - 0xf6, 0x6c, 0xbe, 0xae, 0xed, 0xf9, 0xe4, 0xa2, 0xc1, 0xbf, 0x95, 0xe9, 0x2d, 0x16, 0xcc, 0xbe, - 0xfd, 0x7d, 0xae, 0x0f, 0xca, 0x26, 0x84, 0x77, 0xc4, 0x7e, 0xd2, 0x84, 0x90, 0xb6, 0x3f, 0xf7, - 0xaf, 0xd7, 0xfe, 0x6c, 0x43, 0x45, 0xea, 0xfc, 0x0e, 0x54, 0x64, 0x4d, 0x27, 0x1b, 0x04, 0x31, - 0x3a, 0x6f, 0x10, 0x0a, 0xb2, 0x4e, 0xd7, 0x7e, 0xae, 0x40, 0x59, 0x0f, 0x43, 0x3f, 0xd4, 0xfe, - 0x48, 0x81, 0x3a, 0x3e, 0xed, 0xf9, 0x0e, 0xe3, 0xd9, 0x60, 0xb7, 0xdb, 0xb3, 0xa8, 0xfe, 0xcd, - 0x91, 0x8e, 0xd9, 0xa0, 0x0d, 0x77, 0xf6, 0x86, 0x83, 0xbd, 0x23, 0x4a, 0xf5, 0x81, 0x69, 0x99, - 0xb4, 0x3b, 0x18, 0xf1, 0xb6, 0x67, 0x38, 0x50, 0x15, 0x9e, 0x29, 0x8c, 0x81, 0xa9, 0xd3, 0x41, - 0xb7, 0x6f, 0x89, 0x56, 0xb4, 0x88, 0x77, 0xb3, 0xba, 0xde, 0xb3, 0xf0, 0xd6, 0x51, 0x2d, 0xf1, - 0x96, 0xd5, 0x34, 0x0e, 0xf4, 0xe1, 0x91, 0xa9, 0x96, 0xc9, 0x6d, 0x58, 0x3f, 0xd4, 0xe9, 0x81, - 0x31, 0x1a, 0x19, 0xc3, 0x81, 0xd5, 0xd3, 0x07, 0x86, 0xde, 0x53, 0x2b, 0x7c, 0x9d, 0x5d, 0x63, - 0xdf, 0xec, 0xee, 0xf6, 0x75, 0xb9, 0x4e, 0x95, 0x6c, 0xc2, 0x5b, 0x7b, 0xc3, 0x83, 0x03, 0xc3, - 0x34, 0xf5, 0x9e, 0xb5, 0x7b, 0x64, 0x5a, 0x23, 0xd3, 0xe8, 0xf7, 0xad, 0xee, 0xe1, 0x61, 0xff, - 0x29, 0x4f, 0x60, 0x35, 0x72, 0x17, 0x36, 0xf6, 0xba, 0x87, 0xdd, 0x5d, 0xa3, 0x6f, 0x98, 0x4f, - 0xad, 0x9e, 0x31, 0xe2, 0xf3, 0x7b, 0x6a, 0x9d, 0x27, 0x6c, 0x93, 0x3e, 0xb5, 0xba, 0x7d, 0x14, - 0xcd, 0xd4, 0xad, 0xdd, 0xee, 0xde, 0x13, 0x7d, 0xd0, 0x53, 0x81, 0x0b, 0x30, 0xea, 0x3e, 0xd2, - 0x2d, 0x2e, 0x92, 0x65, 0x0e, 0x87, 0xd6, 0xb0, 0xdf, 0x53, 0x1b, 0xda, 0xbf, 0x14, 0xa1, 0xb4, - 0xe7, 0x47, 0x31, 0xf7, 0x46, 0xe1, 0xac, 0x2f, 0x42, 0x37, 0x66, 0xa2, 0x7f, 0x2b, 0x53, 0xd1, - 0x4b, 0x7f, 0x87, 0x24, 0x1e, 0x50, 0x32, 0x10, 0xeb, 0xd9, 0x19, 0xc7, 0x29, 0x88, 0x5b, 0x3b, - 0xc7, 0xed, 0x72, 0xb2, 0x88, 0x68, 0x78, 0x85, 0x23, 0xd7, 0x2b, 0x22, 0x4e, 0x06, 0x61, 0xb9, - 0xe0, 0xc7, 0x40, 0xb2, 0x20, 0xb9, 0x62, 0x09, 0x91, 0x6a, 0x06, 0x29, 0x96, 0xdc, 0x01, 0x18, - 0xfb, 0xb3, 0x99, 0x1b, 0x8f, 0xfd, 0x28, 0x96, 0x5f, 0xc8, 0xda, 0x39, 0x63, 0x8f, 0x62, 0x6e, - 0xf1, 0x33, 0x37, 0xe6, 0x8f, 0x34, 0x83, 0x26, 0x3b, 0x70, 0xcf, 0x0e, 0x82, 0xd0, 0x7f, 0xe9, - 0xce, 0xec, 0x98, 0x59, 0xdc, 0x73, 0xed, 0x63, 0x66, 0x39, 0x6c, 0x1a, 0xdb, 0xd8, 0x13, 0x95, - 0xe9, 0xdd, 0x0c, 0x60, 0x24, 0xf8, 0x3d, 0xce, 0xe6, 0x71, 0xd7, 0x75, 0xac, 0x88, 0xfd, 0x30, - 0xe7, 0x1e, 0x60, 0xcd, 0x03, 0xc7, 0xe6, 0x62, 0xd6, 0x45, 0x96, 0x72, 0x9d, 0x91, 0xe4, 0x1c, - 0x09, 0x46, 0xfb, 0x15, 0xc0, 0xb9, 0x14, 0x64, 0x1b, 0x6e, 0xf3, 0x3a, 0x9e, 0x45, 0x31, 0x73, - 0x2c, 0xb9, 0xdb, 0x60, 0x1e, 0x47, 0x18, 0xe2, 0xcb, 0x74, 0x23, 0x65, 0xca, 0x9b, 0xc2, 0x79, - 0x1c, 0x91, 0x9f, 0x40, 0xeb, 0xc2, 0x1c, 0x87, 0x4d, 0x19, 0x7f, 0x6d, 0x15, 0xa7, 0xdd, 0x59, - 0x98, 0xd6, 0x13, 0x5c, 0xed, 0x4f, 0x14, 0x80, 0x7d, 0x16, 0x53, 0xc1, 0xcd, 0x34, 0xb6, 0x95, - 0xeb, 0x36, 0xb6, 0xef, 0x27, 0x17, 0x08, 0xc5, 0xab, 0x63, 0xc0, 0x42, 0x97, 0xa1, 0xdc, 0xa4, - 0xcb, 0xc8, 0x35, 0x11, 0xc5, 0x2b, 0x9a, 0x88, 0x52, 0xae, 0x89, 0xf8, 0x18, 0x9a, 0xf6, 0x74, - 0xea, 0xbf, 0xe0, 0x05, 0x0d, 0x0b, 0x43, 0xe6, 0xa0, 0x11, 0x9c, 0xd7, 0xdb, 0xc8, 0xec, 0x49, - 0x9e, 0xf6, 0xe7, 0x0a, 0x34, 0x50, 0x15, 0x51, 0xe0, 0x7b, 0x11, 0x23, 0x5f, 0x42, 0x45, 0x5e, - 0x44, 0x8b, 0x8b, 0xfc, 0xb7, 0x33, 0xb2, 0x66, 0x70, 0xb2, 0x68, 0xa0, 0x12, 0xcc, 0x33, 0x42, - 0xe6, 0x75, 0x97, 0x2b, 0x25, 0x45, 0x91, 0xfb, 0x50, 0x73, 0x3d, 0x4b, 0xb4, 0xd4, 0x95, 0x4c, - 0x58, 0xac, 0xba, 0x1e, 0xd6, 0xb2, 0xed, 0x57, 0x50, 0x11, 0x2f, 0x21, 0x9d, 0x54, 0xa6, 0x8b, - 0xfa, 0xcb, 0xdc, 0x1c, 0xa7, 0xc2, 0xc8, 0xc3, 0x29, 0xbd, 0x2e, 0x40, 0xb7, 0xa0, 0x7a, 0xca, - 0x9b, 0x0f, 0xbc, 0xf4, 0xe3, 0xea, 0x4d, 0x86, 0xda, 0x1f, 0x97, 0x00, 0x0e, 0xe7, 0x4b, 0x0c, - 0xa4, 0x71, 0x5d, 0x03, 0xe9, 0xe4, 0xf4, 0xf8, 0x7a, 0x99, 0x7f, 0x75, 0x43, 0x59, 0xd2, 0x69, - 0x17, 0x6f, 0xda, 0x69, 0xdf, 0x87, 0x6a, 0x1c, 0xce, 0xb9, 0xa3, 0x08, 0x63, 0x4a, 0x5b, 0x5a, - 0x49, 0x25, 0x6f, 0x42, 0x79, 0xe2, 0x87, 0x63, 0x86, 0x8e, 0x95, 0xb2, 0x05, 0xed, 0xc2, 0x65, - 0x52, 0xed, 0xb2, 0xcb, 0x24, 0xde, 0xa0, 0x45, 0xf2, 0x1e, 0x0d, 0x0b, 0x99, 0x7c, 0x83, 0x96, - 0x5c, 0xb1, 0xd1, 0x14, 0x44, 0xbe, 0x81, 0xa6, 0x3d, 0x8f, 0x7d, 0xcb, 0xe5, 0x15, 0xda, 0xd4, - 0x1d, 0x9f, 0x61, 0xd9, 0xdd, 0xcc, 0x7f, 0xaf, 0x4f, 0x0f, 0xaa, 0xd3, 0x9d, 0xc7, 0xbe, 0xe1, - 0x1c, 0x22, 0x72, 0xa7, 0x2a, 0x93, 0x12, 0x5d, 0xb1, 0x33, 0x64, 0xed, 0xc7, 0xb0, 0x92, 0x85, - 0xf1, 0x04, 0x24, 0x81, 0xea, 0x1b, 0x3c, 0x3b, 0x8d, 0x78, 0x6a, 0x1b, 0x98, 0x46, 0xb7, 0xaf, - 0x16, 0xb4, 0x18, 0x1a, 0xb8, 0xbc, 0xf4, 0x8e, 0xeb, 0xba, 0xfd, 0x03, 0x28, 0x61, 0xf8, 0x55, - 0x2e, 0x7c, 0x0f, 0xc1, 0x98, 0x8b, 0xcc, 0xbc, 0xf9, 0x15, 0xb3, 0xe6, 0xf7, 0xdf, 0x05, 0x58, - 0x31, 0xfd, 0xf9, 0xf8, 0xe4, 0xa2, 0x01, 0xc2, 0xaf, 0x3b, 0x42, 0x2d, 0x31, 0x1f, 0xe5, 0xa6, - 0xe6, 0x93, 0x5a, 0x47, 0x71, 0x89, 0x75, 0xdc, 0xf4, 0xcc, 0xb5, 0x2f, 0x60, 0x55, 0x6e, 0x5e, - 0x6a, 0x3d, 0xd1, 0x66, 0xe1, 0x0a, 0x6d, 0x6a, 0xbf, 0x50, 0x60, 0x55, 0xc4, 0xf7, 0xff, 0xbb, - 0xd2, 0x2a, 0x37, 0x0c, 0xeb, 0xe5, 0x1b, 0x5d, 0x1e, 0xfd, 0xbf, 0xf4, 0x34, 0x6d, 0x08, 0xcd, - 0x44, 0x7d, 0x37, 0x50, 0xfb, 0x15, 0x46, 0xfc, 0x8b, 0x02, 0x34, 0x06, 0xec, 0xe5, 0x92, 0x20, - 0x5a, 0xbe, 0xee, 0x71, 0x7c, 0x98, 0x2b, 0x57, 0x1b, 0xdb, 0xeb, 0x59, 0x19, 0xc4, 0xd5, 0x63, - 0x52, 0xc1, 0xa6, 0xb7, 0xa8, 0xca, 0xf2, 0x5b, 0xd4, 0xd2, 0x62, 0xb7, 0x9e, 0xb9, 0xc5, 0x2b, - 0x2e, 0xbb, 0xc5, 0xd3, 0xfe, 0xad, 0x08, 0x0d, 0x6c, 0x90, 0x29, 0x8b, 0xe6, 0xd3, 0x38, 0x27, - 0x4c, 0xe1, 0x6a, 0x61, 0x3a, 0x50, 0x09, 0x71, 0x92, 0x74, 0xa5, 0x4b, 0x83, 0xbf, 0x40, 0x61, - 0x6b, 0xfc, 0xdc, 0x0d, 0x02, 0xe6, 0x58, 0x82, 0x92, 0x14, 0x30, 0x4d, 0x49, 0x16, 0x22, 0x44, - 0xbc, 0xfc, 0x9c, 0xf9, 0x21, 0x4b, 0x51, 0x45, 0xbc, 0x4f, 0x68, 0x70, 0x5a, 0x02, 0xc9, 0xdd, - 0x37, 0x88, 0xca, 0xe0, 0xfc, 0xbe, 0x21, 0xed, 0x35, 0x91, 0x5b, 0x47, 0xae, 0xe8, 0x35, 0x91, - 0xcd, 0xbb, 0xa8, 0x99, 0x3d, 0x9d, 0x5a, 0x7e, 0x10, 0xa1, 0xd3, 0xd4, 0x68, 0x0d, 0x09, 0xc3, - 0x20, 0x22, 0x5f, 0x43, 0x7a, 0x5d, 0x2c, 0x6f, 0xc9, 0xc5, 0x39, 0xb6, 0x2e, 0xbb, 0x58, 0xa0, - 0xab, 0xe3, 0xdc, 0xfd, 0xcf, 0x92, 0x1b, 0xea, 0xca, 0x4d, 0x6f, 0xa8, 0x1f, 0x42, 0x59, 0xc4, - 0xa8, 0xda, 0xeb, 0x62, 0x94, 0xc0, 0x65, 0xed, 0xb3, 0x91, 0xb7, 0xcf, 0x5f, 0x16, 0x80, 0x74, - 0xa7, 0x53, 0x7f, 0x6c, 0xc7, 0xcc, 0x70, 0xa2, 0x8b, 0x66, 0x7a, 0xed, 0xcf, 0x2e, 0x9f, 0x41, - 0x7d, 0xe6, 0x3b, 0x6c, 0x6a, 0x25, 0xdf, 0x94, 0x2e, 0xad, 0x7e, 0x10, 0xc6, 0x5b, 0x52, 0x02, - 0x25, 0xbc, 0xc4, 0x51, 0xb0, 0xee, 0xc0, 0x67, 0xde, 0x84, 0xcd, 0xec, 0x97, 0xb2, 0x14, 0xe1, - 0x8f, 0xa4, 0x03, 0xd5, 0x90, 0x45, 0x2c, 0x3c, 0x65, 0x57, 0x16, 0x55, 0x09, 0x48, 0x7b, 0x06, - 0x1b, 0xb9, 0x1d, 0x49, 0x47, 0xbe, 0x85, 0x5f, 0x2b, 0xc3, 0x58, 0x7e, 0xb4, 0x12, 0x03, 0xfe, - 0x3a, 0xe6, 0x25, 0x9f, 0x41, 0xf9, 0x63, 0xea, 0xf0, 0xc5, 0xab, 0xe2, 0xec, 0x1e, 0xa8, 0x59, - 0x4d, 0xbb, 0x63, 0x0c, 0x36, 0xf2, 0x54, 0x0a, 0xd7, 0x3b, 0x15, 0xed, 0xef, 0x0a, 0xb0, 0xde, - 0x75, 0x1c, 0xf1, 0x77, 0xc3, 0x25, 0xaa, 0x2f, 0x5e, 0x57, 0xf5, 0x0b, 0x81, 0x58, 0x84, 0x89, - 0x6b, 0x05, 0xe2, 0x0f, 0xa1, 0x92, 0xd6, 0x5a, 0xc5, 0x05, 0x77, 0x16, 0x72, 0x51, 0x09, 0xd0, - 0x6e, 0x01, 0xc9, 0x0a, 0x2b, 0xb4, 0xaa, 0xfd, 0x69, 0x11, 0xee, 0xee, 0xb2, 0x63, 0xd7, 0xcb, - 0xbe, 0xe2, 0x57, 0xdf, 0xc9, 0xc5, 0x4f, 0x65, 0x9f, 0xc1, 0xba, 0x28, 0xe4, 0x93, 0x7f, 0x62, - 0x59, 0xec, 0x58, 0x7e, 0x9d, 0x94, 0xb1, 0x6a, 0x0d, 0xf9, 0x07, 0x92, 0xad, 0xe3, 0x7f, 0xc5, - 0x1c, 0x3b, 0xb6, 0x9f, 0xd9, 0x11, 0xb3, 0x5c, 0x47, 0xfe, 0x59, 0x06, 0x12, 0x92, 0xe1, 0x90, - 0x21, 0x94, 0xb8, 0x0d, 0xa2, 0xeb, 0x36, 0xb7, 0xb7, 0x33, 0x62, 0x5d, 0xb2, 0x95, 0xac, 0x02, - 0x0f, 0x7c, 0x87, 0xed, 0x54, 0x8f, 0x06, 0x4f, 0x06, 0xc3, 0xef, 0x06, 0x14, 0x17, 0x22, 0x06, - 0xdc, 0x0a, 0x42, 0x76, 0xea, 0xfa, 0xf3, 0xc8, 0xca, 0x9e, 0x44, 0xf5, 0xca, 0x94, 0xb8, 0x91, - 0xcc, 0xc9, 0x10, 0xb5, 0x9f, 0xc2, 0xda, 0xc2, 0xcb, 0x78, 0x6d, 0x26, 0x5f, 0xa7, 0xbe, 0x41, - 0x56, 0xa1, 0x8e, 0x1f, 0xbb, 0x97, 0x7f, 0xfb, 0xd6, 0xfe, 0xb5, 0x80, 0x57, 0x4c, 0x33, 0x37, - 0xbe, 0x59, 0x06, 0xfb, 0xcd, 0x7c, 0x06, 0x83, 0xed, 0x77, 0xf3, 0xe6, 0x9b, 0x59, 0xb0, 0xf3, - 0xad, 0x00, 0xa6, 0x41, 0xa4, 0x6d, 0x43, 0x55, 0xd2, 0xc8, 0x6f, 0xc1, 0x5a, 0xe8, 0xfb, 0x71, - 0xd2, 0x89, 0x8a, 0x0e, 0xe4, 0xf2, 0x3f, 0xdb, 0xac, 0x72, 0xb0, 0x48, 0x06, 0x4f, 0xf2, 0xbd, - 0x48, 0x59, 0xfc, 0x0d, 0x44, 0x0e, 0x77, 0x1b, 0xbf, 0x5b, 0x4f, 0xff, 0xb7, 0xfb, 0xbf, 0x01, - 0x00, 0x00, 0xff, 0xff, 0x35, 0x9f, 0x30, 0x98, 0xf2, 0x2b, 0x00, 0x00, -} diff --git a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto deleted file mode 100644 index 497b4d9a..00000000 --- a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto +++ /dev/null @@ -1,551 +0,0 @@ -syntax = "proto2"; -option go_package = "datastore"; - -package appengine; - -message Action{} - -message PropertyValue { - optional int64 int64Value = 1; - optional bool booleanValue = 2; - optional string stringValue = 3; - optional double doubleValue = 4; - - optional group PointValue = 5 { - required double x = 6; - required double y = 7; - } - - optional group UserValue = 8 { - required string email = 9; - required string auth_domain = 10; - optional string nickname = 11; - optional string federated_identity = 21; - optional string federated_provider = 22; - } - - optional group ReferenceValue = 12 { - required string app = 13; - optional string name_space = 20; - repeated group PathElement = 14 { - required string type = 15; - optional int64 id = 16; - optional string name = 17; - } - } -} - -message Property { - enum Meaning { - NO_MEANING = 0; - BLOB = 14; - TEXT = 15; - BYTESTRING = 16; - - ATOM_CATEGORY = 1; - ATOM_LINK = 2; - ATOM_TITLE = 3; - ATOM_CONTENT = 4; - ATOM_SUMMARY = 5; - ATOM_AUTHOR = 6; - - GD_WHEN = 7; - GD_EMAIL = 8; - GEORSS_POINT = 9; - GD_IM = 10; - - GD_PHONENUMBER = 11; - GD_POSTALADDRESS = 12; - - GD_RATING = 13; - - BLOBKEY = 17; - ENTITY_PROTO = 19; - - INDEX_VALUE = 18; - }; - - optional Meaning meaning = 1 [default = NO_MEANING]; - optional string meaning_uri = 2; - - required string name = 3; - - required PropertyValue value = 5; - - required bool multiple = 4; - - optional bool searchable = 6 [default=false]; - - enum FtsTokenizationOption { - HTML = 1; - ATOM = 2; - } - - optional FtsTokenizationOption fts_tokenization_option = 8; - - optional string locale = 9 [default = "en"]; -} - -message Path { - repeated group Element = 1 { - required string type = 2; - optional int64 id = 3; - optional string name = 4; - } -} - -message Reference { - required string app = 13; - optional string name_space = 20; - required Path path = 14; -} - -message User { - required string email = 1; - required string auth_domain = 2; - optional string nickname = 3; - optional string federated_identity = 6; - optional string federated_provider = 7; -} - -message EntityProto { - required Reference key = 13; - required Path entity_group = 16; - optional User owner = 17; - - enum Kind { - GD_CONTACT = 1; - GD_EVENT = 2; - GD_MESSAGE = 3; - } - optional Kind kind = 4; - optional string kind_uri = 5; - - repeated Property property = 14; - repeated Property raw_property = 15; - - optional int32 rank = 18; -} - -message CompositeProperty { - required int64 index_id = 1; - repeated string value = 2; -} - -message Index { - required string entity_type = 1; - required bool ancestor = 5; - repeated group Property = 2 { - required string name = 3; - enum Direction { - ASCENDING = 1; - DESCENDING = 2; - } - optional Direction direction = 4 [default = ASCENDING]; - } -} - -message CompositeIndex { - required string app_id = 1; - required int64 id = 2; - required Index definition = 3; - - enum State { - WRITE_ONLY = 1; - READ_WRITE = 2; - DELETED = 3; - ERROR = 4; - } - required State state = 4; - - optional bool only_use_if_required = 6 [default = false]; -} - -message IndexPostfix { - message IndexValue { - required string property_name = 1; - required PropertyValue value = 2; - } - - repeated IndexValue index_value = 1; - - optional Reference key = 2; - - optional bool before = 3 [default=true]; -} - -message IndexPosition { - optional string key = 1; - - optional bool before = 2 [default=true]; -} - -message Snapshot { - enum Status { - INACTIVE = 0; - ACTIVE = 1; - } - - required int64 ts = 1; -} - -message InternalHeader { - optional string qos = 1; -} - -message Transaction { - optional InternalHeader header = 4; - required fixed64 handle = 1; - required string app = 2; - optional bool mark_changes = 3 [default = false]; -} - -message Query { - optional InternalHeader header = 39; - - required string app = 1; - optional string name_space = 29; - - optional string kind = 3; - optional Reference ancestor = 17; - - repeated group Filter = 4 { - enum Operator { - LESS_THAN = 1; - LESS_THAN_OR_EQUAL = 2; - GREATER_THAN = 3; - GREATER_THAN_OR_EQUAL = 4; - EQUAL = 5; - IN = 6; - EXISTS = 7; - } - - required Operator op = 6; - repeated Property property = 14; - } - - optional string search_query = 8; - - repeated group Order = 9 { - enum Direction { - ASCENDING = 1; - DESCENDING = 2; - } - - required string property = 10; - optional Direction direction = 11 [default = ASCENDING]; - } - - enum Hint { - ORDER_FIRST = 1; - ANCESTOR_FIRST = 2; - FILTER_FIRST = 3; - } - optional Hint hint = 18; - - optional int32 count = 23; - - optional int32 offset = 12 [default = 0]; - - optional int32 limit = 16; - - optional CompiledCursor compiled_cursor = 30; - optional CompiledCursor end_compiled_cursor = 31; - - repeated CompositeIndex composite_index = 19; - - optional bool require_perfect_plan = 20 [default = false]; - - optional bool keys_only = 21 [default = false]; - - optional Transaction transaction = 22; - - optional bool compile = 25 [default = false]; - - optional int64 failover_ms = 26; - - optional bool strong = 32; - - repeated string property_name = 33; - - repeated string group_by_property_name = 34; - - optional bool distinct = 24; - - optional int64 min_safe_time_seconds = 35; - - repeated string safe_replica_name = 36; - - optional bool persist_offset = 37 [default=false]; -} - -message CompiledQuery { - required group PrimaryScan = 1 { - optional string index_name = 2; - - optional string start_key = 3; - optional bool start_inclusive = 4; - optional string end_key = 5; - optional bool end_inclusive = 6; - - repeated string start_postfix_value = 22; - repeated string end_postfix_value = 23; - - optional int64 end_unapplied_log_timestamp_us = 19; - } - - repeated group MergeJoinScan = 7 { - required string index_name = 8; - - repeated string prefix_value = 9; - - optional bool value_prefix = 20 [default=false]; - } - - optional Index index_def = 21; - - optional int32 offset = 10 [default = 0]; - - optional int32 limit = 11; - - required bool keys_only = 12; - - repeated string property_name = 24; - - optional int32 distinct_infix_size = 25; - - optional group EntityFilter = 13 { - optional bool distinct = 14 [default=false]; - - optional string kind = 17; - optional Reference ancestor = 18; - } -} - -message CompiledCursor { - optional group Position = 2 { - optional string start_key = 27; - - repeated group IndexValue = 29 { - optional string property = 30; - required PropertyValue value = 31; - } - - optional Reference key = 32; - - optional bool start_inclusive = 28 [default=true]; - } -} - -message Cursor { - required fixed64 cursor = 1; - - optional string app = 2; -} - -message Error { - enum ErrorCode { - BAD_REQUEST = 1; - CONCURRENT_TRANSACTION = 2; - INTERNAL_ERROR = 3; - NEED_INDEX = 4; - TIMEOUT = 5; - PERMISSION_DENIED = 6; - BIGTABLE_ERROR = 7; - COMMITTED_BUT_STILL_APPLYING = 8; - CAPABILITY_DISABLED = 9; - TRY_ALTERNATE_BACKEND = 10; - SAFE_TIME_TOO_OLD = 11; - } -} - -message Cost { - optional int32 index_writes = 1; - optional int32 index_write_bytes = 2; - optional int32 entity_writes = 3; - optional int32 entity_write_bytes = 4; - optional group CommitCost = 5 { - optional int32 requested_entity_puts = 6; - optional int32 requested_entity_deletes = 7; - }; - optional int32 approximate_storage_delta = 8; - optional int32 id_sequence_updates = 9; -} - -message GetRequest { - optional InternalHeader header = 6; - - repeated Reference key = 1; - optional Transaction transaction = 2; - - optional int64 failover_ms = 3; - - optional bool strong = 4; - - optional bool allow_deferred = 5 [default=false]; -} - -message GetResponse { - repeated group Entity = 1 { - optional EntityProto entity = 2; - optional Reference key = 4; - - optional int64 version = 3; - } - - repeated Reference deferred = 5; - - optional bool in_order = 6 [default=true]; -} - -message PutRequest { - optional InternalHeader header = 11; - - repeated EntityProto entity = 1; - optional Transaction transaction = 2; - repeated CompositeIndex composite_index = 3; - - optional bool trusted = 4 [default = false]; - - optional bool force = 7 [default = false]; - - optional bool mark_changes = 8 [default = false]; - repeated Snapshot snapshot = 9; - - enum AutoIdPolicy { - CURRENT = 0; - SEQUENTIAL = 1; - } - optional AutoIdPolicy auto_id_policy = 10 [default = CURRENT]; -} - -message PutResponse { - repeated Reference key = 1; - optional Cost cost = 2; - repeated int64 version = 3; -} - -message TouchRequest { - optional InternalHeader header = 10; - - repeated Reference key = 1; - repeated CompositeIndex composite_index = 2; - optional bool force = 3 [default = false]; - repeated Snapshot snapshot = 9; -} - -message TouchResponse { - optional Cost cost = 1; -} - -message DeleteRequest { - optional InternalHeader header = 10; - - repeated Reference key = 6; - optional Transaction transaction = 5; - - optional bool trusted = 4 [default = false]; - - optional bool force = 7 [default = false]; - - optional bool mark_changes = 8 [default = false]; - repeated Snapshot snapshot = 9; -} - -message DeleteResponse { - optional Cost cost = 1; - repeated int64 version = 3; -} - -message NextRequest { - optional InternalHeader header = 5; - - required Cursor cursor = 1; - optional int32 count = 2; - - optional int32 offset = 4 [default = 0]; - - optional bool compile = 3 [default = false]; -} - -message QueryResult { - optional Cursor cursor = 1; - - repeated EntityProto result = 2; - - optional int32 skipped_results = 7; - - required bool more_results = 3; - - optional bool keys_only = 4; - - optional bool index_only = 9; - - optional bool small_ops = 10; - - optional CompiledQuery compiled_query = 5; - - optional CompiledCursor compiled_cursor = 6; - - repeated CompositeIndex index = 8; - - repeated int64 version = 11; -} - -message AllocateIdsRequest { - optional InternalHeader header = 4; - - optional Reference model_key = 1; - - optional int64 size = 2; - - optional int64 max = 3; - - repeated Reference reserve = 5; -} - -message AllocateIdsResponse { - required int64 start = 1; - required int64 end = 2; - optional Cost cost = 3; -} - -message CompositeIndices { - repeated CompositeIndex index = 1; -} - -message AddActionsRequest { - optional InternalHeader header = 3; - - required Transaction transaction = 1; - repeated Action action = 2; -} - -message AddActionsResponse { -} - -message BeginTransactionRequest { - optional InternalHeader header = 3; - - required string app = 1; - optional bool allow_multiple_eg = 2 [default = false]; - optional string database_id = 4; - - enum TransactionMode { - UNKNOWN = 0; - READ_ONLY = 1; - READ_WRITE = 2; - } - optional TransactionMode mode = 5 [default = UNKNOWN]; - - optional Transaction previous_transaction = 7; -} - -message CommitResponse { - optional Cost cost = 1; - - repeated group Version = 3 { - required Reference root_entity_key = 4; - required int64 version = 5; - } -} diff --git a/vendor/google.golang.org/appengine/internal/identity.go b/vendor/google.golang.org/appengine/internal/identity.go deleted file mode 100644 index 0f95aa91..00000000 --- a/vendor/google.golang.org/appengine/internal/identity.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package internal - -import ( - "context" - "os" -) - -var ( - // This is set to true in identity_classic.go, which is behind the appengine build tag. - // The appengine build tag is set for the first generation runtimes (<= Go 1.9) but not - // the second generation runtimes (>= Go 1.11), so this indicates whether we're on a - // first-gen runtime. See IsStandard below for the second-gen check. - appengineStandard bool - - // This is set to true in identity_flex.go, which is behind the appenginevm build tag. - appengineFlex bool -) - -// AppID is the implementation of the wrapper function of the same name in -// ../identity.go. See that file for commentary. -func AppID(c context.Context) string { - return appID(FullyQualifiedAppID(c)) -} - -// IsStandard is the implementation of the wrapper function of the same name in -// ../appengine.go. See that file for commentary. -func IsStandard() bool { - // appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not - // second-gen (>= Go 1.11). - return appengineStandard || IsSecondGen() -} - -// IsSecondGen is the implementation of the wrapper function of the same name in -// ../appengine.go. See that file for commentary. -func IsSecondGen() bool { - // Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime. - return os.Getenv("GAE_ENV") == "standard" -} - -// IsFlex is the implementation of the wrapper function of the same name in -// ../appengine.go. See that file for commentary. -func IsFlex() bool { - return appengineFlex -} - -// IsAppEngine is the implementation of the wrapper function of the same name in -// ../appengine.go. See that file for commentary. -func IsAppEngine() bool { - return IsStandard() || IsFlex() -} diff --git a/vendor/google.golang.org/appengine/internal/identity_classic.go b/vendor/google.golang.org/appengine/internal/identity_classic.go deleted file mode 100644 index 5ad3548b..00000000 --- a/vendor/google.golang.org/appengine/internal/identity_classic.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build appengine -// +build appengine - -package internal - -import ( - "context" - - "appengine" -) - -func init() { - appengineStandard = true -} - -func DefaultVersionHostname(ctx context.Context) string { - c := fromContext(ctx) - if c == nil { - panic(errNotAppEngineContext) - } - return appengine.DefaultVersionHostname(c) -} - -func Datacenter(_ context.Context) string { return appengine.Datacenter() } -func ServerSoftware() string { return appengine.ServerSoftware() } -func InstanceID() string { return appengine.InstanceID() } -func IsDevAppServer() bool { return appengine.IsDevAppServer() } - -func RequestID(ctx context.Context) string { - c := fromContext(ctx) - if c == nil { - panic(errNotAppEngineContext) - } - return appengine.RequestID(c) -} - -func ModuleName(ctx context.Context) string { - c := fromContext(ctx) - if c == nil { - panic(errNotAppEngineContext) - } - return appengine.ModuleName(c) -} -func VersionID(ctx context.Context) string { - c := fromContext(ctx) - if c == nil { - panic(errNotAppEngineContext) - } - return appengine.VersionID(c) -} - -func fullyQualifiedAppID(ctx context.Context) string { - c := fromContext(ctx) - if c == nil { - panic(errNotAppEngineContext) - } - return c.FullyQualifiedAppID() -} diff --git a/vendor/google.golang.org/appengine/internal/identity_flex.go b/vendor/google.golang.org/appengine/internal/identity_flex.go deleted file mode 100644 index 4201b6b5..00000000 --- a/vendor/google.golang.org/appengine/internal/identity_flex.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 Google LLC. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build appenginevm -// +build appenginevm - -package internal - -func init() { - appengineFlex = true -} diff --git a/vendor/google.golang.org/appengine/internal/identity_vm.go b/vendor/google.golang.org/appengine/internal/identity_vm.go deleted file mode 100644 index 18ddda3a..00000000 --- a/vendor/google.golang.org/appengine/internal/identity_vm.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build !appengine -// +build !appengine - -package internal - -import ( - "context" - "log" - "net/http" - "os" - "strings" -) - -// These functions are implementations of the wrapper functions -// in ../appengine/identity.go. See that file for commentary. - -const ( - hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname" - hRequestLogId = "X-AppEngine-Request-Log-Id" - hDatacenter = "X-AppEngine-Datacenter" -) - -func ctxHeaders(ctx context.Context) http.Header { - c := fromContext(ctx) - if c == nil { - return nil - } - return c.Request().Header -} - -func DefaultVersionHostname(ctx context.Context) string { - return ctxHeaders(ctx).Get(hDefaultVersionHostname) -} - -func RequestID(ctx context.Context) string { - return ctxHeaders(ctx).Get(hRequestLogId) -} - -func Datacenter(ctx context.Context) string { - if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" { - return dc - } - // If the header isn't set, read zone from the metadata service. - // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE] - zone, err := getMetadata("instance/zone") - if err != nil { - log.Printf("Datacenter: %v", err) - return "" - } - parts := strings.Split(string(zone), "/") - if len(parts) == 0 { - return "" - } - return parts[len(parts)-1] -} - -func ServerSoftware() string { - // TODO(dsymonds): Remove fallback when we've verified this. - if s := os.Getenv("SERVER_SOFTWARE"); s != "" { - return s - } - if s := os.Getenv("GAE_ENV"); s != "" { - return s - } - return "Google App Engine/1.x.x" -} - -// TODO(dsymonds): Remove the metadata fetches. - -func ModuleName(_ context.Context) string { - if s := os.Getenv("GAE_MODULE_NAME"); s != "" { - return s - } - if s := os.Getenv("GAE_SERVICE"); s != "" { - return s - } - return string(mustGetMetadata("instance/attributes/gae_backend_name")) -} - -func VersionID(_ context.Context) string { - if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" { - return s1 + "." + s2 - } - if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" { - return s1 + "." + s2 - } - return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version")) -} - -func InstanceID() string { - if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" { - return s - } - if s := os.Getenv("GAE_INSTANCE"); s != "" { - return s - } - return string(mustGetMetadata("instance/attributes/gae_backend_instance")) -} - -func partitionlessAppID() string { - // gae_project has everything except the partition prefix. - if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" { - return appID - } - if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" { - return project - } - return string(mustGetMetadata("instance/attributes/gae_project")) -} - -func fullyQualifiedAppID(_ context.Context) string { - if s := os.Getenv("GAE_APPLICATION"); s != "" { - return s - } - appID := partitionlessAppID() - - part := os.Getenv("GAE_PARTITION") - if part == "" { - part = string(mustGetMetadata("instance/attributes/gae_partition")) - } - - if part != "" { - appID = part + "~" + appID - } - return appID -} - -func IsDevAppServer() bool { - return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" || os.Getenv("GAE_ENV") == "localdev" -} diff --git a/vendor/google.golang.org/appengine/internal/internal.go b/vendor/google.golang.org/appengine/internal/internal.go deleted file mode 100644 index 051ea398..00000000 --- a/vendor/google.golang.org/appengine/internal/internal.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// Package internal provides support for package appengine. -// -// Programs should not use this package directly. Its API is not stable. -// Use packages appengine and appengine/* instead. -package internal - -import ( - "fmt" - - "github.com/golang/protobuf/proto" - - remotepb "google.golang.org/appengine/internal/remote_api" -) - -// errorCodeMaps is a map of service name to the error code map for the service. -var errorCodeMaps = make(map[string]map[int32]string) - -// RegisterErrorCodeMap is called from API implementations to register their -// error code map. This should only be called from init functions. -func RegisterErrorCodeMap(service string, m map[int32]string) { - errorCodeMaps[service] = m -} - -type timeoutCodeKey struct { - service string - code int32 -} - -// timeoutCodes is the set of service+code pairs that represent timeouts. -var timeoutCodes = make(map[timeoutCodeKey]bool) - -func RegisterTimeoutErrorCode(service string, code int32) { - timeoutCodes[timeoutCodeKey{service, code}] = true -} - -// APIError is the type returned by appengine.Context's Call method -// when an API call fails in an API-specific way. This may be, for instance, -// a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE. -type APIError struct { - Service string - Detail string - Code int32 // API-specific error code -} - -func (e *APIError) Error() string { - if e.Code == 0 { - if e.Detail == "" { - return "APIError <empty>" - } - return e.Detail - } - s := fmt.Sprintf("API error %d", e.Code) - if m, ok := errorCodeMaps[e.Service]; ok { - s += " (" + e.Service + ": " + m[e.Code] + ")" - } else { - // Shouldn't happen, but provide a bit more detail if it does. - s = e.Service + " " + s - } - if e.Detail != "" { - s += ": " + e.Detail - } - return s -} - -func (e *APIError) IsTimeout() bool { - return timeoutCodes[timeoutCodeKey{e.Service, e.Code}] -} - -// CallError is the type returned by appengine.Context's Call method when an -// API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED. -type CallError struct { - Detail string - Code int32 - // TODO: Remove this if we get a distinguishable error code. - Timeout bool -} - -func (e *CallError) Error() string { - var msg string - switch remotepb.RpcError_ErrorCode(e.Code) { - case remotepb.RpcError_UNKNOWN: - return e.Detail - case remotepb.RpcError_OVER_QUOTA: - msg = "Over quota" - case remotepb.RpcError_CAPABILITY_DISABLED: - msg = "Capability disabled" - case remotepb.RpcError_CANCELLED: - msg = "Canceled" - default: - msg = fmt.Sprintf("Call error %d", e.Code) - } - s := msg + ": " + e.Detail - if e.Timeout { - s += " (timeout)" - } - return s -} - -func (e *CallError) IsTimeout() bool { - return e.Timeout -} - -// NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace. -// The function should be prepared to be called on the same message more than once; it should only modify the -// RPC request the first time. -var NamespaceMods = make(map[string]func(m proto.Message, namespace string)) diff --git a/vendor/google.golang.org/appengine/internal/log/log_service.pb.go b/vendor/google.golang.org/appengine/internal/log/log_service.pb.go deleted file mode 100644 index 8545ac4a..00000000 --- a/vendor/google.golang.org/appengine/internal/log/log_service.pb.go +++ /dev/null @@ -1,1313 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google.golang.org/appengine/internal/log/log_service.proto - -package log - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type LogServiceError_ErrorCode int32 - -const ( - LogServiceError_OK LogServiceError_ErrorCode = 0 - LogServiceError_INVALID_REQUEST LogServiceError_ErrorCode = 1 - LogServiceError_STORAGE_ERROR LogServiceError_ErrorCode = 2 -) - -var LogServiceError_ErrorCode_name = map[int32]string{ - 0: "OK", - 1: "INVALID_REQUEST", - 2: "STORAGE_ERROR", -} -var LogServiceError_ErrorCode_value = map[string]int32{ - "OK": 0, - "INVALID_REQUEST": 1, - "STORAGE_ERROR": 2, -} - -func (x LogServiceError_ErrorCode) Enum() *LogServiceError_ErrorCode { - p := new(LogServiceError_ErrorCode) - *p = x - return p -} -func (x LogServiceError_ErrorCode) String() string { - return proto.EnumName(LogServiceError_ErrorCode_name, int32(x)) -} -func (x *LogServiceError_ErrorCode) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(LogServiceError_ErrorCode_value, data, "LogServiceError_ErrorCode") - if err != nil { - return err - } - *x = LogServiceError_ErrorCode(value) - return nil -} -func (LogServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{0, 0} -} - -type LogServiceError struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogServiceError) Reset() { *m = LogServiceError{} } -func (m *LogServiceError) String() string { return proto.CompactTextString(m) } -func (*LogServiceError) ProtoMessage() {} -func (*LogServiceError) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{0} -} -func (m *LogServiceError) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogServiceError.Unmarshal(m, b) -} -func (m *LogServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogServiceError.Marshal(b, m, deterministic) -} -func (dst *LogServiceError) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogServiceError.Merge(dst, src) -} -func (m *LogServiceError) XXX_Size() int { - return xxx_messageInfo_LogServiceError.Size(m) -} -func (m *LogServiceError) XXX_DiscardUnknown() { - xxx_messageInfo_LogServiceError.DiscardUnknown(m) -} - -var xxx_messageInfo_LogServiceError proto.InternalMessageInfo - -type UserAppLogLine struct { - TimestampUsec *int64 `protobuf:"varint,1,req,name=timestamp_usec,json=timestampUsec" json:"timestamp_usec,omitempty"` - Level *int64 `protobuf:"varint,2,req,name=level" json:"level,omitempty"` - Message *string `protobuf:"bytes,3,req,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *UserAppLogLine) Reset() { *m = UserAppLogLine{} } -func (m *UserAppLogLine) String() string { return proto.CompactTextString(m) } -func (*UserAppLogLine) ProtoMessage() {} -func (*UserAppLogLine) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{1} -} -func (m *UserAppLogLine) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_UserAppLogLine.Unmarshal(m, b) -} -func (m *UserAppLogLine) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_UserAppLogLine.Marshal(b, m, deterministic) -} -func (dst *UserAppLogLine) XXX_Merge(src proto.Message) { - xxx_messageInfo_UserAppLogLine.Merge(dst, src) -} -func (m *UserAppLogLine) XXX_Size() int { - return xxx_messageInfo_UserAppLogLine.Size(m) -} -func (m *UserAppLogLine) XXX_DiscardUnknown() { - xxx_messageInfo_UserAppLogLine.DiscardUnknown(m) -} - -var xxx_messageInfo_UserAppLogLine proto.InternalMessageInfo - -func (m *UserAppLogLine) GetTimestampUsec() int64 { - if m != nil && m.TimestampUsec != nil { - return *m.TimestampUsec - } - return 0 -} - -func (m *UserAppLogLine) GetLevel() int64 { - if m != nil && m.Level != nil { - return *m.Level - } - return 0 -} - -func (m *UserAppLogLine) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -type UserAppLogGroup struct { - LogLine []*UserAppLogLine `protobuf:"bytes,2,rep,name=log_line,json=logLine" json:"log_line,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *UserAppLogGroup) Reset() { *m = UserAppLogGroup{} } -func (m *UserAppLogGroup) String() string { return proto.CompactTextString(m) } -func (*UserAppLogGroup) ProtoMessage() {} -func (*UserAppLogGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{2} -} -func (m *UserAppLogGroup) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_UserAppLogGroup.Unmarshal(m, b) -} -func (m *UserAppLogGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_UserAppLogGroup.Marshal(b, m, deterministic) -} -func (dst *UserAppLogGroup) XXX_Merge(src proto.Message) { - xxx_messageInfo_UserAppLogGroup.Merge(dst, src) -} -func (m *UserAppLogGroup) XXX_Size() int { - return xxx_messageInfo_UserAppLogGroup.Size(m) -} -func (m *UserAppLogGroup) XXX_DiscardUnknown() { - xxx_messageInfo_UserAppLogGroup.DiscardUnknown(m) -} - -var xxx_messageInfo_UserAppLogGroup proto.InternalMessageInfo - -func (m *UserAppLogGroup) GetLogLine() []*UserAppLogLine { - if m != nil { - return m.LogLine - } - return nil -} - -type FlushRequest struct { - Logs []byte `protobuf:"bytes,1,opt,name=logs" json:"logs,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *FlushRequest) Reset() { *m = FlushRequest{} } -func (m *FlushRequest) String() string { return proto.CompactTextString(m) } -func (*FlushRequest) ProtoMessage() {} -func (*FlushRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{3} -} -func (m *FlushRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FlushRequest.Unmarshal(m, b) -} -func (m *FlushRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FlushRequest.Marshal(b, m, deterministic) -} -func (dst *FlushRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_FlushRequest.Merge(dst, src) -} -func (m *FlushRequest) XXX_Size() int { - return xxx_messageInfo_FlushRequest.Size(m) -} -func (m *FlushRequest) XXX_DiscardUnknown() { - xxx_messageInfo_FlushRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_FlushRequest proto.InternalMessageInfo - -func (m *FlushRequest) GetLogs() []byte { - if m != nil { - return m.Logs - } - return nil -} - -type SetStatusRequest struct { - Status *string `protobuf:"bytes,1,req,name=status" json:"status,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SetStatusRequest) Reset() { *m = SetStatusRequest{} } -func (m *SetStatusRequest) String() string { return proto.CompactTextString(m) } -func (*SetStatusRequest) ProtoMessage() {} -func (*SetStatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{4} -} -func (m *SetStatusRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SetStatusRequest.Unmarshal(m, b) -} -func (m *SetStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SetStatusRequest.Marshal(b, m, deterministic) -} -func (dst *SetStatusRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetStatusRequest.Merge(dst, src) -} -func (m *SetStatusRequest) XXX_Size() int { - return xxx_messageInfo_SetStatusRequest.Size(m) -} -func (m *SetStatusRequest) XXX_DiscardUnknown() { - xxx_messageInfo_SetStatusRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_SetStatusRequest proto.InternalMessageInfo - -func (m *SetStatusRequest) GetStatus() string { - if m != nil && m.Status != nil { - return *m.Status - } - return "" -} - -type LogOffset struct { - RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId" json:"request_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogOffset) Reset() { *m = LogOffset{} } -func (m *LogOffset) String() string { return proto.CompactTextString(m) } -func (*LogOffset) ProtoMessage() {} -func (*LogOffset) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{5} -} -func (m *LogOffset) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogOffset.Unmarshal(m, b) -} -func (m *LogOffset) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogOffset.Marshal(b, m, deterministic) -} -func (dst *LogOffset) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogOffset.Merge(dst, src) -} -func (m *LogOffset) XXX_Size() int { - return xxx_messageInfo_LogOffset.Size(m) -} -func (m *LogOffset) XXX_DiscardUnknown() { - xxx_messageInfo_LogOffset.DiscardUnknown(m) -} - -var xxx_messageInfo_LogOffset proto.InternalMessageInfo - -func (m *LogOffset) GetRequestId() []byte { - if m != nil { - return m.RequestId - } - return nil -} - -type LogLine struct { - Time *int64 `protobuf:"varint,1,req,name=time" json:"time,omitempty"` - Level *int32 `protobuf:"varint,2,req,name=level" json:"level,omitempty"` - LogMessage *string `protobuf:"bytes,3,req,name=log_message,json=logMessage" json:"log_message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogLine) Reset() { *m = LogLine{} } -func (m *LogLine) String() string { return proto.CompactTextString(m) } -func (*LogLine) ProtoMessage() {} -func (*LogLine) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{6} -} -func (m *LogLine) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogLine.Unmarshal(m, b) -} -func (m *LogLine) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogLine.Marshal(b, m, deterministic) -} -func (dst *LogLine) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogLine.Merge(dst, src) -} -func (m *LogLine) XXX_Size() int { - return xxx_messageInfo_LogLine.Size(m) -} -func (m *LogLine) XXX_DiscardUnknown() { - xxx_messageInfo_LogLine.DiscardUnknown(m) -} - -var xxx_messageInfo_LogLine proto.InternalMessageInfo - -func (m *LogLine) GetTime() int64 { - if m != nil && m.Time != nil { - return *m.Time - } - return 0 -} - -func (m *LogLine) GetLevel() int32 { - if m != nil && m.Level != nil { - return *m.Level - } - return 0 -} - -func (m *LogLine) GetLogMessage() string { - if m != nil && m.LogMessage != nil { - return *m.LogMessage - } - return "" -} - -type RequestLog struct { - AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` - ModuleId *string `protobuf:"bytes,37,opt,name=module_id,json=moduleId,def=default" json:"module_id,omitempty"` - VersionId *string `protobuf:"bytes,2,req,name=version_id,json=versionId" json:"version_id,omitempty"` - RequestId []byte `protobuf:"bytes,3,req,name=request_id,json=requestId" json:"request_id,omitempty"` - Offset *LogOffset `protobuf:"bytes,35,opt,name=offset" json:"offset,omitempty"` - Ip *string `protobuf:"bytes,4,req,name=ip" json:"ip,omitempty"` - Nickname *string `protobuf:"bytes,5,opt,name=nickname" json:"nickname,omitempty"` - StartTime *int64 `protobuf:"varint,6,req,name=start_time,json=startTime" json:"start_time,omitempty"` - EndTime *int64 `protobuf:"varint,7,req,name=end_time,json=endTime" json:"end_time,omitempty"` - Latency *int64 `protobuf:"varint,8,req,name=latency" json:"latency,omitempty"` - Mcycles *int64 `protobuf:"varint,9,req,name=mcycles" json:"mcycles,omitempty"` - Method *string `protobuf:"bytes,10,req,name=method" json:"method,omitempty"` - Resource *string `protobuf:"bytes,11,req,name=resource" json:"resource,omitempty"` - HttpVersion *string `protobuf:"bytes,12,req,name=http_version,json=httpVersion" json:"http_version,omitempty"` - Status *int32 `protobuf:"varint,13,req,name=status" json:"status,omitempty"` - ResponseSize *int64 `protobuf:"varint,14,req,name=response_size,json=responseSize" json:"response_size,omitempty"` - Referrer *string `protobuf:"bytes,15,opt,name=referrer" json:"referrer,omitempty"` - UserAgent *string `protobuf:"bytes,16,opt,name=user_agent,json=userAgent" json:"user_agent,omitempty"` - UrlMapEntry *string `protobuf:"bytes,17,req,name=url_map_entry,json=urlMapEntry" json:"url_map_entry,omitempty"` - Combined *string `protobuf:"bytes,18,req,name=combined" json:"combined,omitempty"` - ApiMcycles *int64 `protobuf:"varint,19,opt,name=api_mcycles,json=apiMcycles" json:"api_mcycles,omitempty"` - Host *string `protobuf:"bytes,20,opt,name=host" json:"host,omitempty"` - Cost *float64 `protobuf:"fixed64,21,opt,name=cost" json:"cost,omitempty"` - TaskQueueName *string `protobuf:"bytes,22,opt,name=task_queue_name,json=taskQueueName" json:"task_queue_name,omitempty"` - TaskName *string `protobuf:"bytes,23,opt,name=task_name,json=taskName" json:"task_name,omitempty"` - WasLoadingRequest *bool `protobuf:"varint,24,opt,name=was_loading_request,json=wasLoadingRequest" json:"was_loading_request,omitempty"` - PendingTime *int64 `protobuf:"varint,25,opt,name=pending_time,json=pendingTime" json:"pending_time,omitempty"` - ReplicaIndex *int32 `protobuf:"varint,26,opt,name=replica_index,json=replicaIndex,def=-1" json:"replica_index,omitempty"` - Finished *bool `protobuf:"varint,27,opt,name=finished,def=1" json:"finished,omitempty"` - CloneKey []byte `protobuf:"bytes,28,opt,name=clone_key,json=cloneKey" json:"clone_key,omitempty"` - Line []*LogLine `protobuf:"bytes,29,rep,name=line" json:"line,omitempty"` - LinesIncomplete *bool `protobuf:"varint,36,opt,name=lines_incomplete,json=linesIncomplete" json:"lines_incomplete,omitempty"` - AppEngineRelease []byte `protobuf:"bytes,38,opt,name=app_engine_release,json=appEngineRelease" json:"app_engine_release,omitempty"` - ExitReason *int32 `protobuf:"varint,30,opt,name=exit_reason,json=exitReason" json:"exit_reason,omitempty"` - WasThrottledForTime *bool `protobuf:"varint,31,opt,name=was_throttled_for_time,json=wasThrottledForTime" json:"was_throttled_for_time,omitempty"` - WasThrottledForRequests *bool `protobuf:"varint,32,opt,name=was_throttled_for_requests,json=wasThrottledForRequests" json:"was_throttled_for_requests,omitempty"` - ThrottledTime *int64 `protobuf:"varint,33,opt,name=throttled_time,json=throttledTime" json:"throttled_time,omitempty"` - ServerName []byte `protobuf:"bytes,34,opt,name=server_name,json=serverName" json:"server_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RequestLog) Reset() { *m = RequestLog{} } -func (m *RequestLog) String() string { return proto.CompactTextString(m) } -func (*RequestLog) ProtoMessage() {} -func (*RequestLog) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{7} -} -func (m *RequestLog) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RequestLog.Unmarshal(m, b) -} -func (m *RequestLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RequestLog.Marshal(b, m, deterministic) -} -func (dst *RequestLog) XXX_Merge(src proto.Message) { - xxx_messageInfo_RequestLog.Merge(dst, src) -} -func (m *RequestLog) XXX_Size() int { - return xxx_messageInfo_RequestLog.Size(m) -} -func (m *RequestLog) XXX_DiscardUnknown() { - xxx_messageInfo_RequestLog.DiscardUnknown(m) -} - -var xxx_messageInfo_RequestLog proto.InternalMessageInfo - -const Default_RequestLog_ModuleId string = "default" -const Default_RequestLog_ReplicaIndex int32 = -1 -const Default_RequestLog_Finished bool = true - -func (m *RequestLog) GetAppId() string { - if m != nil && m.AppId != nil { - return *m.AppId - } - return "" -} - -func (m *RequestLog) GetModuleId() string { - if m != nil && m.ModuleId != nil { - return *m.ModuleId - } - return Default_RequestLog_ModuleId -} - -func (m *RequestLog) GetVersionId() string { - if m != nil && m.VersionId != nil { - return *m.VersionId - } - return "" -} - -func (m *RequestLog) GetRequestId() []byte { - if m != nil { - return m.RequestId - } - return nil -} - -func (m *RequestLog) GetOffset() *LogOffset { - if m != nil { - return m.Offset - } - return nil -} - -func (m *RequestLog) GetIp() string { - if m != nil && m.Ip != nil { - return *m.Ip - } - return "" -} - -func (m *RequestLog) GetNickname() string { - if m != nil && m.Nickname != nil { - return *m.Nickname - } - return "" -} - -func (m *RequestLog) GetStartTime() int64 { - if m != nil && m.StartTime != nil { - return *m.StartTime - } - return 0 -} - -func (m *RequestLog) GetEndTime() int64 { - if m != nil && m.EndTime != nil { - return *m.EndTime - } - return 0 -} - -func (m *RequestLog) GetLatency() int64 { - if m != nil && m.Latency != nil { - return *m.Latency - } - return 0 -} - -func (m *RequestLog) GetMcycles() int64 { - if m != nil && m.Mcycles != nil { - return *m.Mcycles - } - return 0 -} - -func (m *RequestLog) GetMethod() string { - if m != nil && m.Method != nil { - return *m.Method - } - return "" -} - -func (m *RequestLog) GetResource() string { - if m != nil && m.Resource != nil { - return *m.Resource - } - return "" -} - -func (m *RequestLog) GetHttpVersion() string { - if m != nil && m.HttpVersion != nil { - return *m.HttpVersion - } - return "" -} - -func (m *RequestLog) GetStatus() int32 { - if m != nil && m.Status != nil { - return *m.Status - } - return 0 -} - -func (m *RequestLog) GetResponseSize() int64 { - if m != nil && m.ResponseSize != nil { - return *m.ResponseSize - } - return 0 -} - -func (m *RequestLog) GetReferrer() string { - if m != nil && m.Referrer != nil { - return *m.Referrer - } - return "" -} - -func (m *RequestLog) GetUserAgent() string { - if m != nil && m.UserAgent != nil { - return *m.UserAgent - } - return "" -} - -func (m *RequestLog) GetUrlMapEntry() string { - if m != nil && m.UrlMapEntry != nil { - return *m.UrlMapEntry - } - return "" -} - -func (m *RequestLog) GetCombined() string { - if m != nil && m.Combined != nil { - return *m.Combined - } - return "" -} - -func (m *RequestLog) GetApiMcycles() int64 { - if m != nil && m.ApiMcycles != nil { - return *m.ApiMcycles - } - return 0 -} - -func (m *RequestLog) GetHost() string { - if m != nil && m.Host != nil { - return *m.Host - } - return "" -} - -func (m *RequestLog) GetCost() float64 { - if m != nil && m.Cost != nil { - return *m.Cost - } - return 0 -} - -func (m *RequestLog) GetTaskQueueName() string { - if m != nil && m.TaskQueueName != nil { - return *m.TaskQueueName - } - return "" -} - -func (m *RequestLog) GetTaskName() string { - if m != nil && m.TaskName != nil { - return *m.TaskName - } - return "" -} - -func (m *RequestLog) GetWasLoadingRequest() bool { - if m != nil && m.WasLoadingRequest != nil { - return *m.WasLoadingRequest - } - return false -} - -func (m *RequestLog) GetPendingTime() int64 { - if m != nil && m.PendingTime != nil { - return *m.PendingTime - } - return 0 -} - -func (m *RequestLog) GetReplicaIndex() int32 { - if m != nil && m.ReplicaIndex != nil { - return *m.ReplicaIndex - } - return Default_RequestLog_ReplicaIndex -} - -func (m *RequestLog) GetFinished() bool { - if m != nil && m.Finished != nil { - return *m.Finished - } - return Default_RequestLog_Finished -} - -func (m *RequestLog) GetCloneKey() []byte { - if m != nil { - return m.CloneKey - } - return nil -} - -func (m *RequestLog) GetLine() []*LogLine { - if m != nil { - return m.Line - } - return nil -} - -func (m *RequestLog) GetLinesIncomplete() bool { - if m != nil && m.LinesIncomplete != nil { - return *m.LinesIncomplete - } - return false -} - -func (m *RequestLog) GetAppEngineRelease() []byte { - if m != nil { - return m.AppEngineRelease - } - return nil -} - -func (m *RequestLog) GetExitReason() int32 { - if m != nil && m.ExitReason != nil { - return *m.ExitReason - } - return 0 -} - -func (m *RequestLog) GetWasThrottledForTime() bool { - if m != nil && m.WasThrottledForTime != nil { - return *m.WasThrottledForTime - } - return false -} - -func (m *RequestLog) GetWasThrottledForRequests() bool { - if m != nil && m.WasThrottledForRequests != nil { - return *m.WasThrottledForRequests - } - return false -} - -func (m *RequestLog) GetThrottledTime() int64 { - if m != nil && m.ThrottledTime != nil { - return *m.ThrottledTime - } - return 0 -} - -func (m *RequestLog) GetServerName() []byte { - if m != nil { - return m.ServerName - } - return nil -} - -type LogModuleVersion struct { - ModuleId *string `protobuf:"bytes,1,opt,name=module_id,json=moduleId,def=default" json:"module_id,omitempty"` - VersionId *string `protobuf:"bytes,2,opt,name=version_id,json=versionId" json:"version_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogModuleVersion) Reset() { *m = LogModuleVersion{} } -func (m *LogModuleVersion) String() string { return proto.CompactTextString(m) } -func (*LogModuleVersion) ProtoMessage() {} -func (*LogModuleVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{8} -} -func (m *LogModuleVersion) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogModuleVersion.Unmarshal(m, b) -} -func (m *LogModuleVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogModuleVersion.Marshal(b, m, deterministic) -} -func (dst *LogModuleVersion) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogModuleVersion.Merge(dst, src) -} -func (m *LogModuleVersion) XXX_Size() int { - return xxx_messageInfo_LogModuleVersion.Size(m) -} -func (m *LogModuleVersion) XXX_DiscardUnknown() { - xxx_messageInfo_LogModuleVersion.DiscardUnknown(m) -} - -var xxx_messageInfo_LogModuleVersion proto.InternalMessageInfo - -const Default_LogModuleVersion_ModuleId string = "default" - -func (m *LogModuleVersion) GetModuleId() string { - if m != nil && m.ModuleId != nil { - return *m.ModuleId - } - return Default_LogModuleVersion_ModuleId -} - -func (m *LogModuleVersion) GetVersionId() string { - if m != nil && m.VersionId != nil { - return *m.VersionId - } - return "" -} - -type LogReadRequest struct { - AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` - VersionId []string `protobuf:"bytes,2,rep,name=version_id,json=versionId" json:"version_id,omitempty"` - ModuleVersion []*LogModuleVersion `protobuf:"bytes,19,rep,name=module_version,json=moduleVersion" json:"module_version,omitempty"` - StartTime *int64 `protobuf:"varint,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"` - EndTime *int64 `protobuf:"varint,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"` - Offset *LogOffset `protobuf:"bytes,5,opt,name=offset" json:"offset,omitempty"` - RequestId [][]byte `protobuf:"bytes,6,rep,name=request_id,json=requestId" json:"request_id,omitempty"` - MinimumLogLevel *int32 `protobuf:"varint,7,opt,name=minimum_log_level,json=minimumLogLevel" json:"minimum_log_level,omitempty"` - IncludeIncomplete *bool `protobuf:"varint,8,opt,name=include_incomplete,json=includeIncomplete" json:"include_incomplete,omitempty"` - Count *int64 `protobuf:"varint,9,opt,name=count" json:"count,omitempty"` - CombinedLogRegex *string `protobuf:"bytes,14,opt,name=combined_log_regex,json=combinedLogRegex" json:"combined_log_regex,omitempty"` - HostRegex *string `protobuf:"bytes,15,opt,name=host_regex,json=hostRegex" json:"host_regex,omitempty"` - ReplicaIndex *int32 `protobuf:"varint,16,opt,name=replica_index,json=replicaIndex" json:"replica_index,omitempty"` - IncludeAppLogs *bool `protobuf:"varint,10,opt,name=include_app_logs,json=includeAppLogs" json:"include_app_logs,omitempty"` - AppLogsPerRequest *int32 `protobuf:"varint,17,opt,name=app_logs_per_request,json=appLogsPerRequest" json:"app_logs_per_request,omitempty"` - IncludeHost *bool `protobuf:"varint,11,opt,name=include_host,json=includeHost" json:"include_host,omitempty"` - IncludeAll *bool `protobuf:"varint,12,opt,name=include_all,json=includeAll" json:"include_all,omitempty"` - CacheIterator *bool `protobuf:"varint,13,opt,name=cache_iterator,json=cacheIterator" json:"cache_iterator,omitempty"` - NumShards *int32 `protobuf:"varint,18,opt,name=num_shards,json=numShards" json:"num_shards,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogReadRequest) Reset() { *m = LogReadRequest{} } -func (m *LogReadRequest) String() string { return proto.CompactTextString(m) } -func (*LogReadRequest) ProtoMessage() {} -func (*LogReadRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{9} -} -func (m *LogReadRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogReadRequest.Unmarshal(m, b) -} -func (m *LogReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogReadRequest.Marshal(b, m, deterministic) -} -func (dst *LogReadRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogReadRequest.Merge(dst, src) -} -func (m *LogReadRequest) XXX_Size() int { - return xxx_messageInfo_LogReadRequest.Size(m) -} -func (m *LogReadRequest) XXX_DiscardUnknown() { - xxx_messageInfo_LogReadRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_LogReadRequest proto.InternalMessageInfo - -func (m *LogReadRequest) GetAppId() string { - if m != nil && m.AppId != nil { - return *m.AppId - } - return "" -} - -func (m *LogReadRequest) GetVersionId() []string { - if m != nil { - return m.VersionId - } - return nil -} - -func (m *LogReadRequest) GetModuleVersion() []*LogModuleVersion { - if m != nil { - return m.ModuleVersion - } - return nil -} - -func (m *LogReadRequest) GetStartTime() int64 { - if m != nil && m.StartTime != nil { - return *m.StartTime - } - return 0 -} - -func (m *LogReadRequest) GetEndTime() int64 { - if m != nil && m.EndTime != nil { - return *m.EndTime - } - return 0 -} - -func (m *LogReadRequest) GetOffset() *LogOffset { - if m != nil { - return m.Offset - } - return nil -} - -func (m *LogReadRequest) GetRequestId() [][]byte { - if m != nil { - return m.RequestId - } - return nil -} - -func (m *LogReadRequest) GetMinimumLogLevel() int32 { - if m != nil && m.MinimumLogLevel != nil { - return *m.MinimumLogLevel - } - return 0 -} - -func (m *LogReadRequest) GetIncludeIncomplete() bool { - if m != nil && m.IncludeIncomplete != nil { - return *m.IncludeIncomplete - } - return false -} - -func (m *LogReadRequest) GetCount() int64 { - if m != nil && m.Count != nil { - return *m.Count - } - return 0 -} - -func (m *LogReadRequest) GetCombinedLogRegex() string { - if m != nil && m.CombinedLogRegex != nil { - return *m.CombinedLogRegex - } - return "" -} - -func (m *LogReadRequest) GetHostRegex() string { - if m != nil && m.HostRegex != nil { - return *m.HostRegex - } - return "" -} - -func (m *LogReadRequest) GetReplicaIndex() int32 { - if m != nil && m.ReplicaIndex != nil { - return *m.ReplicaIndex - } - return 0 -} - -func (m *LogReadRequest) GetIncludeAppLogs() bool { - if m != nil && m.IncludeAppLogs != nil { - return *m.IncludeAppLogs - } - return false -} - -func (m *LogReadRequest) GetAppLogsPerRequest() int32 { - if m != nil && m.AppLogsPerRequest != nil { - return *m.AppLogsPerRequest - } - return 0 -} - -func (m *LogReadRequest) GetIncludeHost() bool { - if m != nil && m.IncludeHost != nil { - return *m.IncludeHost - } - return false -} - -func (m *LogReadRequest) GetIncludeAll() bool { - if m != nil && m.IncludeAll != nil { - return *m.IncludeAll - } - return false -} - -func (m *LogReadRequest) GetCacheIterator() bool { - if m != nil && m.CacheIterator != nil { - return *m.CacheIterator - } - return false -} - -func (m *LogReadRequest) GetNumShards() int32 { - if m != nil && m.NumShards != nil { - return *m.NumShards - } - return 0 -} - -type LogReadResponse struct { - Log []*RequestLog `protobuf:"bytes,1,rep,name=log" json:"log,omitempty"` - Offset *LogOffset `protobuf:"bytes,2,opt,name=offset" json:"offset,omitempty"` - LastEndTime *int64 `protobuf:"varint,3,opt,name=last_end_time,json=lastEndTime" json:"last_end_time,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogReadResponse) Reset() { *m = LogReadResponse{} } -func (m *LogReadResponse) String() string { return proto.CompactTextString(m) } -func (*LogReadResponse) ProtoMessage() {} -func (*LogReadResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{10} -} -func (m *LogReadResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogReadResponse.Unmarshal(m, b) -} -func (m *LogReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogReadResponse.Marshal(b, m, deterministic) -} -func (dst *LogReadResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogReadResponse.Merge(dst, src) -} -func (m *LogReadResponse) XXX_Size() int { - return xxx_messageInfo_LogReadResponse.Size(m) -} -func (m *LogReadResponse) XXX_DiscardUnknown() { - xxx_messageInfo_LogReadResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_LogReadResponse proto.InternalMessageInfo - -func (m *LogReadResponse) GetLog() []*RequestLog { - if m != nil { - return m.Log - } - return nil -} - -func (m *LogReadResponse) GetOffset() *LogOffset { - if m != nil { - return m.Offset - } - return nil -} - -func (m *LogReadResponse) GetLastEndTime() int64 { - if m != nil && m.LastEndTime != nil { - return *m.LastEndTime - } - return 0 -} - -type LogUsageRecord struct { - VersionId *string `protobuf:"bytes,1,opt,name=version_id,json=versionId" json:"version_id,omitempty"` - StartTime *int32 `protobuf:"varint,2,opt,name=start_time,json=startTime" json:"start_time,omitempty"` - EndTime *int32 `protobuf:"varint,3,opt,name=end_time,json=endTime" json:"end_time,omitempty"` - Count *int64 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"` - TotalSize *int64 `protobuf:"varint,5,opt,name=total_size,json=totalSize" json:"total_size,omitempty"` - Records *int32 `protobuf:"varint,6,opt,name=records" json:"records,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogUsageRecord) Reset() { *m = LogUsageRecord{} } -func (m *LogUsageRecord) String() string { return proto.CompactTextString(m) } -func (*LogUsageRecord) ProtoMessage() {} -func (*LogUsageRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{11} -} -func (m *LogUsageRecord) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogUsageRecord.Unmarshal(m, b) -} -func (m *LogUsageRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogUsageRecord.Marshal(b, m, deterministic) -} -func (dst *LogUsageRecord) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogUsageRecord.Merge(dst, src) -} -func (m *LogUsageRecord) XXX_Size() int { - return xxx_messageInfo_LogUsageRecord.Size(m) -} -func (m *LogUsageRecord) XXX_DiscardUnknown() { - xxx_messageInfo_LogUsageRecord.DiscardUnknown(m) -} - -var xxx_messageInfo_LogUsageRecord proto.InternalMessageInfo - -func (m *LogUsageRecord) GetVersionId() string { - if m != nil && m.VersionId != nil { - return *m.VersionId - } - return "" -} - -func (m *LogUsageRecord) GetStartTime() int32 { - if m != nil && m.StartTime != nil { - return *m.StartTime - } - return 0 -} - -func (m *LogUsageRecord) GetEndTime() int32 { - if m != nil && m.EndTime != nil { - return *m.EndTime - } - return 0 -} - -func (m *LogUsageRecord) GetCount() int64 { - if m != nil && m.Count != nil { - return *m.Count - } - return 0 -} - -func (m *LogUsageRecord) GetTotalSize() int64 { - if m != nil && m.TotalSize != nil { - return *m.TotalSize - } - return 0 -} - -func (m *LogUsageRecord) GetRecords() int32 { - if m != nil && m.Records != nil { - return *m.Records - } - return 0 -} - -type LogUsageRequest struct { - AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` - VersionId []string `protobuf:"bytes,2,rep,name=version_id,json=versionId" json:"version_id,omitempty"` - StartTime *int32 `protobuf:"varint,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"` - EndTime *int32 `protobuf:"varint,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"` - ResolutionHours *uint32 `protobuf:"varint,5,opt,name=resolution_hours,json=resolutionHours,def=1" json:"resolution_hours,omitempty"` - CombineVersions *bool `protobuf:"varint,6,opt,name=combine_versions,json=combineVersions" json:"combine_versions,omitempty"` - UsageVersion *int32 `protobuf:"varint,7,opt,name=usage_version,json=usageVersion" json:"usage_version,omitempty"` - VersionsOnly *bool `protobuf:"varint,8,opt,name=versions_only,json=versionsOnly" json:"versions_only,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogUsageRequest) Reset() { *m = LogUsageRequest{} } -func (m *LogUsageRequest) String() string { return proto.CompactTextString(m) } -func (*LogUsageRequest) ProtoMessage() {} -func (*LogUsageRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{12} -} -func (m *LogUsageRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogUsageRequest.Unmarshal(m, b) -} -func (m *LogUsageRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogUsageRequest.Marshal(b, m, deterministic) -} -func (dst *LogUsageRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogUsageRequest.Merge(dst, src) -} -func (m *LogUsageRequest) XXX_Size() int { - return xxx_messageInfo_LogUsageRequest.Size(m) -} -func (m *LogUsageRequest) XXX_DiscardUnknown() { - xxx_messageInfo_LogUsageRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_LogUsageRequest proto.InternalMessageInfo - -const Default_LogUsageRequest_ResolutionHours uint32 = 1 - -func (m *LogUsageRequest) GetAppId() string { - if m != nil && m.AppId != nil { - return *m.AppId - } - return "" -} - -func (m *LogUsageRequest) GetVersionId() []string { - if m != nil { - return m.VersionId - } - return nil -} - -func (m *LogUsageRequest) GetStartTime() int32 { - if m != nil && m.StartTime != nil { - return *m.StartTime - } - return 0 -} - -func (m *LogUsageRequest) GetEndTime() int32 { - if m != nil && m.EndTime != nil { - return *m.EndTime - } - return 0 -} - -func (m *LogUsageRequest) GetResolutionHours() uint32 { - if m != nil && m.ResolutionHours != nil { - return *m.ResolutionHours - } - return Default_LogUsageRequest_ResolutionHours -} - -func (m *LogUsageRequest) GetCombineVersions() bool { - if m != nil && m.CombineVersions != nil { - return *m.CombineVersions - } - return false -} - -func (m *LogUsageRequest) GetUsageVersion() int32 { - if m != nil && m.UsageVersion != nil { - return *m.UsageVersion - } - return 0 -} - -func (m *LogUsageRequest) GetVersionsOnly() bool { - if m != nil && m.VersionsOnly != nil { - return *m.VersionsOnly - } - return false -} - -type LogUsageResponse struct { - Usage []*LogUsageRecord `protobuf:"bytes,1,rep,name=usage" json:"usage,omitempty"` - Summary *LogUsageRecord `protobuf:"bytes,2,opt,name=summary" json:"summary,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LogUsageResponse) Reset() { *m = LogUsageResponse{} } -func (m *LogUsageResponse) String() string { return proto.CompactTextString(m) } -func (*LogUsageResponse) ProtoMessage() {} -func (*LogUsageResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_log_service_f054fd4b5012319d, []int{13} -} -func (m *LogUsageResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LogUsageResponse.Unmarshal(m, b) -} -func (m *LogUsageResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LogUsageResponse.Marshal(b, m, deterministic) -} -func (dst *LogUsageResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_LogUsageResponse.Merge(dst, src) -} -func (m *LogUsageResponse) XXX_Size() int { - return xxx_messageInfo_LogUsageResponse.Size(m) -} -func (m *LogUsageResponse) XXX_DiscardUnknown() { - xxx_messageInfo_LogUsageResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_LogUsageResponse proto.InternalMessageInfo - -func (m *LogUsageResponse) GetUsage() []*LogUsageRecord { - if m != nil { - return m.Usage - } - return nil -} - -func (m *LogUsageResponse) GetSummary() *LogUsageRecord { - if m != nil { - return m.Summary - } - return nil -} - -func init() { - proto.RegisterType((*LogServiceError)(nil), "appengine.LogServiceError") - proto.RegisterType((*UserAppLogLine)(nil), "appengine.UserAppLogLine") - proto.RegisterType((*UserAppLogGroup)(nil), "appengine.UserAppLogGroup") - proto.RegisterType((*FlushRequest)(nil), "appengine.FlushRequest") - proto.RegisterType((*SetStatusRequest)(nil), "appengine.SetStatusRequest") - proto.RegisterType((*LogOffset)(nil), "appengine.LogOffset") - proto.RegisterType((*LogLine)(nil), "appengine.LogLine") - proto.RegisterType((*RequestLog)(nil), "appengine.RequestLog") - proto.RegisterType((*LogModuleVersion)(nil), "appengine.LogModuleVersion") - proto.RegisterType((*LogReadRequest)(nil), "appengine.LogReadRequest") - proto.RegisterType((*LogReadResponse)(nil), "appengine.LogReadResponse") - proto.RegisterType((*LogUsageRecord)(nil), "appengine.LogUsageRecord") - proto.RegisterType((*LogUsageRequest)(nil), "appengine.LogUsageRequest") - proto.RegisterType((*LogUsageResponse)(nil), "appengine.LogUsageResponse") -} - -func init() { - proto.RegisterFile("google.golang.org/appengine/internal/log/log_service.proto", fileDescriptor_log_service_f054fd4b5012319d) -} - -var fileDescriptor_log_service_f054fd4b5012319d = []byte{ - // 1553 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x72, 0xdb, 0xc6, - 0x15, 0x2e, 0x48, 0x51, 0x24, 0x0f, 0x49, 0x91, 0x5a, 0xcb, 0xce, 0xda, 0xae, 0x6b, 0x1a, 0x4e, - 0x1c, 0xd6, 0x93, 0x48, 0x93, 0xa4, 0x57, 0xca, 0x95, 0xd3, 0x2a, 0x8e, 0x26, 0xb4, 0xd5, 0x40, - 0x72, 0x3a, 0xd3, 0x1b, 0x0c, 0x0a, 0x1c, 0x81, 0x18, 0x2f, 0xb1, 0xc8, 0xee, 0xc2, 0x91, 0x72, - 0xdb, 0xdb, 0x3e, 0x46, 0x1f, 0xa2, 0xaf, 0xd2, 0xb7, 0xe9, 0xec, 0xd9, 0x05, 0x44, 0x2a, 0x4d, - 0xc6, 0x33, 0xb9, 0xe0, 0x10, 0xfb, 0x9d, 0x83, 0xdd, 0xf3, 0xf3, 0x9d, 0x6f, 0x01, 0xc7, 0xb9, - 0x94, 0xb9, 0xc0, 0xc3, 0x5c, 0x8a, 0xa4, 0xcc, 0x0f, 0xa5, 0xca, 0x8f, 0x92, 0xaa, 0xc2, 0x32, - 0x2f, 0x4a, 0x3c, 0x2a, 0x4a, 0x83, 0xaa, 0x4c, 0xc4, 0x91, 0x90, 0xb9, 0xfd, 0xc5, 0x1a, 0xd5, - 0xbb, 0x22, 0xc5, 0xc3, 0x4a, 0x49, 0x23, 0xd9, 0xb0, 0xf5, 0x0c, 0x5f, 0xc3, 0x74, 0x29, 0xf3, - 0x73, 0x67, 0x3e, 0x51, 0x4a, 0xaa, 0xf0, 0x4b, 0x18, 0xd2, 0xc3, 0x9f, 0x65, 0x86, 0x6c, 0x17, - 0x3a, 0x67, 0xdf, 0xce, 0x7e, 0xc7, 0xee, 0xc0, 0xf4, 0xf4, 0xf5, 0xf7, 0x2f, 0x96, 0xa7, 0x7f, - 0x89, 0xa3, 0x93, 0xef, 0xde, 0x9c, 0x9c, 0x5f, 0xcc, 0x02, 0xb6, 0x0f, 0x93, 0xf3, 0x8b, 0xb3, - 0xe8, 0xc5, 0xcb, 0x93, 0xf8, 0x24, 0x8a, 0xce, 0xa2, 0x59, 0x27, 0xcc, 0x61, 0xef, 0x8d, 0x46, - 0xf5, 0xa2, 0xaa, 0x96, 0x32, 0x5f, 0x16, 0x25, 0xb2, 0x8f, 0x60, 0xcf, 0x14, 0x6b, 0xd4, 0x26, - 0x59, 0x57, 0x71, 0xad, 0x31, 0xe5, 0xc1, 0xbc, 0xb3, 0xe8, 0x46, 0x93, 0x16, 0x7d, 0xa3, 0x31, - 0x65, 0x07, 0xd0, 0x13, 0xf8, 0x0e, 0x05, 0xef, 0x90, 0xd5, 0x2d, 0x18, 0x87, 0xfe, 0x1a, 0xb5, - 0x4e, 0x72, 0xe4, 0xdd, 0x79, 0x67, 0x31, 0x8c, 0x9a, 0x65, 0xf8, 0x12, 0xa6, 0x37, 0x07, 0xbd, - 0x54, 0xb2, 0xae, 0xd8, 0x9f, 0x60, 0x60, 0x73, 0x15, 0x45, 0x89, 0xbc, 0x33, 0xef, 0x2e, 0x46, - 0x9f, 0xdf, 0x3f, 0x6c, 0x33, 0x3d, 0xdc, 0x0e, 0x2b, 0xea, 0x0b, 0xf7, 0x10, 0x86, 0x30, 0xfe, - 0x5a, 0xd4, 0x7a, 0x15, 0xe1, 0x0f, 0x35, 0x6a, 0xc3, 0x18, 0xec, 0x08, 0x99, 0x6b, 0x1e, 0xcc, - 0x83, 0xc5, 0x38, 0xa2, 0xe7, 0xf0, 0x39, 0xcc, 0xce, 0xd1, 0x9c, 0x9b, 0xc4, 0xd4, 0xba, 0xf1, - 0xbb, 0x07, 0xbb, 0x9a, 0x00, 0xca, 0x67, 0x18, 0xf9, 0x55, 0xf8, 0x1c, 0x86, 0x4b, 0x99, 0x9f, - 0x5d, 0x5e, 0x6a, 0x34, 0xec, 0x11, 0x80, 0x72, 0xfe, 0x71, 0x91, 0xf9, 0x2d, 0x87, 0x1e, 0x39, - 0xcd, 0xc2, 0x0b, 0xe8, 0x37, 0x65, 0x62, 0xb0, 0x63, 0x0b, 0xe2, 0x8b, 0x43, 0xcf, 0xdb, 0x35, - 0xe9, 0x35, 0x35, 0x79, 0x0c, 0x23, 0x9b, 0xe6, 0x76, 0x5d, 0x40, 0xc8, 0xfc, 0x95, 0x2f, 0xcd, - 0x3f, 0x01, 0xc0, 0x47, 0xb9, 0x94, 0x39, 0xbb, 0x0b, 0xbb, 0x49, 0x55, 0xb9, 0xf3, 0xad, 0x6b, - 0x2f, 0xa9, 0xaa, 0xd3, 0x8c, 0x7d, 0x08, 0xc3, 0xb5, 0xcc, 0x6a, 0x81, 0xd6, 0xf2, 0xd1, 0x3c, - 0x58, 0x0c, 0x8f, 0xfb, 0x19, 0x5e, 0x26, 0xb5, 0x30, 0xd1, 0xc0, 0x59, 0x4e, 0x33, 0x9b, 0xc0, - 0x3b, 0x54, 0xba, 0x90, 0xa5, 0x75, 0xeb, 0xd0, 0x06, 0x43, 0x8f, 0x38, 0xf3, 0x46, 0x7e, 0x36, - 0x94, 0xcd, 0xfc, 0xd8, 0x27, 0xb0, 0x2b, 0xa9, 0x10, 0xfc, 0xe9, 0x3c, 0x58, 0x8c, 0x3e, 0x3f, - 0xd8, 0xe8, 0x47, 0x5b, 0xa4, 0xc8, 0xfb, 0xb0, 0x3d, 0xe8, 0x14, 0x15, 0xdf, 0xa1, 0x33, 0x3a, - 0x45, 0xc5, 0x1e, 0xc0, 0xa0, 0x2c, 0xd2, 0xb7, 0x65, 0xb2, 0x46, 0xde, 0xb3, 0x01, 0x46, 0xed, - 0xda, 0x1e, 0xac, 0x4d, 0xa2, 0x4c, 0x4c, 0x45, 0xdb, 0xa5, 0xa2, 0x0d, 0x09, 0xb9, 0xb0, 0x95, - 0xbb, 0x0f, 0x03, 0x2c, 0x33, 0x67, 0xec, 0x93, 0xb1, 0x8f, 0x65, 0x46, 0x26, 0x0e, 0x7d, 0x91, - 0x18, 0x2c, 0xd3, 0x6b, 0x3e, 0x70, 0x16, 0xbf, 0x24, 0xb2, 0xa5, 0xd7, 0xa9, 0x40, 0xcd, 0x87, - 0xce, 0xe2, 0x97, 0xb6, 0xd7, 0x6b, 0x34, 0x2b, 0x99, 0x71, 0x70, 0xbd, 0x76, 0x2b, 0x1b, 0xa1, - 0x42, 0x2d, 0x6b, 0x95, 0x22, 0x1f, 0x91, 0xa5, 0x5d, 0xb3, 0x27, 0x30, 0x5e, 0x19, 0x53, 0xc5, - 0xbe, 0x58, 0x7c, 0x4c, 0xf6, 0x91, 0xc5, 0xbe, 0x77, 0xd0, 0x06, 0x85, 0x26, 0xd4, 0x60, 0xbf, - 0x62, 0x4f, 0x61, 0xa2, 0x50, 0x57, 0xb2, 0xd4, 0x18, 0xeb, 0xe2, 0x27, 0xe4, 0x7b, 0x14, 0xce, - 0xb8, 0x01, 0xcf, 0x8b, 0x9f, 0xd0, 0x9d, 0x7d, 0x89, 0x4a, 0xa1, 0xe2, 0x53, 0x57, 0x9d, 0x66, - 0x6d, 0xab, 0x53, 0x6b, 0x54, 0x71, 0x92, 0x63, 0x69, 0xf8, 0x8c, 0xac, 0x43, 0x8b, 0xbc, 0xb0, - 0x00, 0x0b, 0x61, 0x52, 0x2b, 0x11, 0xaf, 0x93, 0x2a, 0xc6, 0xd2, 0xa8, 0x6b, 0xbe, 0xef, 0x62, - 0xab, 0x95, 0x78, 0x95, 0x54, 0x27, 0x16, 0xb2, 0xdb, 0xa7, 0x72, 0xfd, 0x8f, 0xa2, 0xc4, 0x8c, - 0x33, 0x97, 0x5a, 0xb3, 0xb6, 0x0c, 0x4c, 0xaa, 0x22, 0x6e, 0x8a, 0x75, 0x67, 0x1e, 0x2c, 0xba, - 0x11, 0x24, 0x55, 0xf1, 0xca, 0xd7, 0x8b, 0xc1, 0xce, 0x4a, 0x6a, 0xc3, 0x0f, 0xe8, 0x64, 0x7a, - 0xb6, 0x58, 0x6a, 0xb1, 0xbb, 0xf3, 0x60, 0x11, 0x44, 0xf4, 0xcc, 0x9e, 0xc1, 0xd4, 0x24, 0xfa, - 0x6d, 0xfc, 0x43, 0x8d, 0x35, 0xc6, 0xd4, 0xe8, 0x7b, 0xf4, 0xca, 0xc4, 0xc2, 0xdf, 0x59, 0xf4, - 0xb5, 0xed, 0xf6, 0x43, 0x18, 0x92, 0x1f, 0x79, 0x7c, 0xe0, 0x92, 0xb5, 0x00, 0x19, 0x0f, 0xe1, - 0xce, 0x8f, 0x89, 0x8e, 0x85, 0x4c, 0xb2, 0xa2, 0xcc, 0x63, 0xcf, 0x3e, 0xce, 0xe7, 0xc1, 0x62, - 0x10, 0xed, 0xff, 0x98, 0xe8, 0xa5, 0xb3, 0x34, 0x83, 0xfb, 0x04, 0xc6, 0x15, 0x96, 0xe4, 0x4b, - 0xfc, 0xb8, 0x4f, 0xe1, 0x8f, 0x3c, 0x46, 0x1c, 0xf9, 0xd8, 0x36, 0xa0, 0x12, 0x45, 0x9a, 0xc4, - 0x45, 0x99, 0xe1, 0x15, 0x7f, 0x30, 0x0f, 0x16, 0xbd, 0xe3, 0xce, 0xa7, 0x9f, 0xd9, 0x26, 0x90, - 0xe1, 0xd4, 0xe2, 0x6c, 0x0e, 0x83, 0xcb, 0xa2, 0x2c, 0xf4, 0x0a, 0x33, 0xfe, 0xd0, 0x1e, 0x78, - 0xbc, 0x63, 0x54, 0x8d, 0x51, 0x8b, 0xda, 0xd0, 0x53, 0x21, 0x4b, 0x8c, 0xdf, 0xe2, 0x35, 0xff, - 0x3d, 0x09, 0xc0, 0x80, 0x80, 0x6f, 0xf1, 0x9a, 0x3d, 0x83, 0x1d, 0x52, 0xab, 0x47, 0xa4, 0x56, - 0x6c, 0x7b, 0x3a, 0x48, 0xa6, 0xc8, 0xce, 0xfe, 0x08, 0x33, 0xfb, 0xaf, 0xe3, 0xa2, 0x4c, 0xe5, - 0xba, 0x12, 0x68, 0x90, 0x7f, 0x48, 0xf9, 0x4d, 0x09, 0x3f, 0x6d, 0x61, 0xf6, 0x09, 0x30, 0x3b, - 0xed, 0x6e, 0x9b, 0x58, 0xa1, 0xc0, 0x44, 0x23, 0x7f, 0x46, 0x07, 0xcf, 0x92, 0xaa, 0x3a, 0x21, - 0x43, 0xe4, 0x70, 0xdb, 0x49, 0xbc, 0x2a, 0x4c, 0xac, 0x30, 0xd1, 0xb2, 0xe4, 0x7f, 0xb0, 0x69, - 0x46, 0x60, 0xa1, 0x88, 0x10, 0xf6, 0x05, 0xdc, 0xb3, 0xc5, 0x35, 0x2b, 0x25, 0x8d, 0x11, 0x98, - 0xc5, 0x97, 0x52, 0xb9, 0xb2, 0x3d, 0xa6, 0xf3, 0x6d, 0xe9, 0x2f, 0x1a, 0xe3, 0xd7, 0x52, 0x51, - 0xf9, 0xbe, 0x84, 0x07, 0x3f, 0x7f, 0xc9, 0xf7, 0x45, 0xf3, 0x39, 0xbd, 0xf8, 0xc1, 0xad, 0x17, - 0x7d, 0x77, 0x34, 0xdd, 0x17, 0xed, 0x8b, 0x74, 0xd2, 0x13, 0x6a, 0xd0, 0xa4, 0x45, 0xe9, 0x8c, - 0xc7, 0x30, 0xb2, 0x97, 0x1a, 0x2a, 0x47, 0x8a, 0x90, 0x12, 0x04, 0x07, 0x59, 0x5a, 0x84, 0x7f, - 0x83, 0xd9, 0x52, 0xe6, 0xaf, 0x48, 0xc8, 0x9a, 0x81, 0xdb, 0xd2, 0xbc, 0xe0, 0x7d, 0x35, 0x2f, - 0xd8, 0xd2, 0xbc, 0xf0, 0xbf, 0x3d, 0xd8, 0x5b, 0xca, 0x3c, 0xc2, 0x24, 0x6b, 0x28, 0xf5, 0x0b, - 0x12, 0x7b, 0x7b, 0xa3, 0xee, 0xb6, 0x78, 0x7e, 0x05, 0x7b, 0x3e, 0x9a, 0x46, 0x23, 0xee, 0x10, - 0x0f, 0x1e, 0x6e, 0xf3, 0x60, 0x2b, 0x85, 0x68, 0xb2, 0xde, 0xca, 0x68, 0x5b, 0x07, 0xbb, 0x54, - 0xa9, 0x5f, 0xd0, 0xc1, 0x1d, 0x32, 0xb6, 0x3a, 0x78, 0xa3, 0xcd, 0xbd, 0xf7, 0xd0, 0xe6, 0x6d, - 0xa1, 0xdf, 0x9d, 0x77, 0xb7, 0x85, 0xfe, 0x39, 0xec, 0xaf, 0x8b, 0xb2, 0x58, 0xd7, 0xeb, 0x98, - 0xae, 0x60, 0xba, 0xb5, 0xfa, 0xc4, 0xa6, 0xa9, 0x37, 0x58, 0x46, 0xd3, 0xfd, 0xf5, 0x29, 0xb0, - 0xa2, 0x4c, 0x45, 0x9d, 0xe1, 0x26, 0x9d, 0x07, 0x6e, 0x5c, 0xbd, 0x65, 0x83, 0xd0, 0x07, 0xd0, - 0x4b, 0x65, 0x5d, 0x1a, 0x3e, 0xa4, 0xf8, 0xdd, 0xc2, 0xd2, 0xbc, 0x91, 0x23, 0x3a, 0x51, 0x61, - 0x8e, 0x57, 0x7c, 0x8f, 0x7a, 0x35, 0x6b, 0x2c, 0xd4, 0xa5, 0x1c, 0xaf, 0x6c, 0xf4, 0x56, 0x83, - 0xbc, 0x97, 0x53, 0xcb, 0xa1, 0x45, 0x9c, 0xf9, 0xe9, 0xed, 0x71, 0x9f, 0x51, 0xe4, 0xdb, 0xa3, - 0xbe, 0x80, 0x59, 0x13, 0xb6, 0xed, 0x35, 0x7d, 0x23, 0x00, 0x05, 0xbd, 0xe7, 0x71, 0xf7, 0x75, - 0xa1, 0xd9, 0x11, 0x1c, 0x34, 0x1e, 0x71, 0x85, 0x2d, 0xf3, 0xf9, 0x3e, 0xed, 0xba, 0x9f, 0x38, - 0xb7, 0xbf, 0xa2, 0xda, 0x50, 0xa4, 0x66, 0x6b, 0x92, 0xcd, 0x11, 0x6d, 0x3b, 0xf2, 0xd8, 0x37, - 0x56, 0x29, 0x1f, 0xc3, 0xa8, 0x3d, 0x5d, 0x08, 0x3e, 0x26, 0x0f, 0x68, 0x0e, 0x16, 0xc2, 0x8e, - 0x4d, 0x9a, 0xa4, 0x2b, 0x8c, 0x0b, 0x83, 0x2a, 0x31, 0x52, 0xf1, 0x09, 0xf9, 0x4c, 0x08, 0x3d, - 0xf5, 0xa0, 0xad, 0x44, 0x59, 0xaf, 0x63, 0xbd, 0x4a, 0x54, 0xa6, 0x39, 0xa3, 0x88, 0x86, 0x65, - 0xbd, 0x3e, 0x27, 0x20, 0xfc, 0x57, 0x40, 0xdf, 0x83, 0x8e, 0xdb, 0xee, 0xb2, 0x61, 0x1f, 0x43, - 0x57, 0xc8, 0x9c, 0x07, 0xc4, 0xcd, 0xbb, 0x1b, 0x2c, 0xb9, 0xf9, 0xc6, 0x88, 0xac, 0xc7, 0x06, - 0xa3, 0x3a, 0xef, 0xc1, 0xa8, 0x10, 0x26, 0x22, 0xd1, 0x26, 0x6e, 0xf9, 0xe9, 0xc8, 0x3b, 0xb2, - 0xe0, 0x89, 0xe3, 0x68, 0xf8, 0x9f, 0x80, 0x46, 0xed, 0x8d, 0xfd, 0xac, 0x89, 0x30, 0x95, 0xea, - 0xf6, 0x4c, 0x05, 0xb7, 0x86, 0xf3, 0xd6, 0x3c, 0x74, 0x5c, 0x7e, 0xff, 0x7f, 0x1e, 0xba, 0x64, - 0x6c, 0xe7, 0xa1, 0xe5, 0xd9, 0xce, 0x26, 0xcf, 0x1e, 0x01, 0x18, 0x69, 0x12, 0xe1, 0xee, 0xe1, - 0x9e, 0x9b, 0x2f, 0x42, 0xe8, 0x12, 0xe6, 0xd0, 0x57, 0x14, 0x97, 0xe6, 0xbb, 0x6e, 0x3b, 0xbf, - 0x0c, 0xff, 0xdd, 0xa1, 0x4a, 0xfa, 0xd0, 0x7f, 0x8b, 0x4c, 0xfc, 0x7c, 0xc4, 0x7b, 0xbf, 0x36, - 0xe2, 0xbd, 0xcd, 0x11, 0x9f, 0xd9, 0xcf, 0x11, 0x51, 0x1b, 0xbb, 0xf7, 0x4a, 0xd6, 0x4a, 0x53, - 0x0a, 0x93, 0xe3, 0xe0, 0xb3, 0x68, 0x7a, 0x63, 0xfa, 0xc6, 0x5a, 0xec, 0x25, 0xe3, 0x07, 0xa7, - 0xd1, 0x23, 0x97, 0xd4, 0x20, 0x9a, 0x7a, 0xdc, 0x8b, 0x0e, 0x7d, 0xa0, 0xd4, 0x36, 0xb1, 0x56, - 0xb8, 0xdc, 0xa8, 0x8f, 0x09, 0x6c, 0xa4, 0xe9, 0x29, 0x4c, 0x9a, 0x7d, 0x62, 0x59, 0x8a, 0x6b, - 0x3f, 0xe2, 0xe3, 0x06, 0x3c, 0x2b, 0xc5, 0x75, 0x78, 0x45, 0x2a, 0xed, 0xab, 0xe4, 0x09, 0x77, - 0x04, 0x3d, 0xda, 0xc8, 0x53, 0xee, 0xfe, 0x36, 0x8d, 0x36, 0xc8, 0x10, 0x39, 0x3f, 0xf6, 0x05, - 0xf4, 0x75, 0xbd, 0x5e, 0x27, 0xea, 0xda, 0x33, 0xef, 0x57, 0x5e, 0x69, 0x3c, 0xbf, 0xea, 0xfd, - 0xdd, 0x92, 0xf6, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x70, 0xd9, 0xa0, 0xf8, 0x48, 0x0d, 0x00, - 0x00, -} diff --git a/vendor/google.golang.org/appengine/internal/log/log_service.proto b/vendor/google.golang.org/appengine/internal/log/log_service.proto deleted file mode 100644 index 8981dc47..00000000 --- a/vendor/google.golang.org/appengine/internal/log/log_service.proto +++ /dev/null @@ -1,150 +0,0 @@ -syntax = "proto2"; -option go_package = "log"; - -package appengine; - -message LogServiceError { - enum ErrorCode { - OK = 0; - INVALID_REQUEST = 1; - STORAGE_ERROR = 2; - } -} - -message UserAppLogLine { - required int64 timestamp_usec = 1; - required int64 level = 2; - required string message = 3; -} - -message UserAppLogGroup { - repeated UserAppLogLine log_line = 2; -} - -message FlushRequest { - optional bytes logs = 1; -} - -message SetStatusRequest { - required string status = 1; -} - - -message LogOffset { - optional bytes request_id = 1; -} - -message LogLine { - required int64 time = 1; - required int32 level = 2; - required string log_message = 3; -} - -message RequestLog { - required string app_id = 1; - optional string module_id = 37 [default="default"]; - required string version_id = 2; - required bytes request_id = 3; - optional LogOffset offset = 35; - required string ip = 4; - optional string nickname = 5; - required int64 start_time = 6; - required int64 end_time = 7; - required int64 latency = 8; - required int64 mcycles = 9; - required string method = 10; - required string resource = 11; - required string http_version = 12; - required int32 status = 13; - required int64 response_size = 14; - optional string referrer = 15; - optional string user_agent = 16; - required string url_map_entry = 17; - required string combined = 18; - optional int64 api_mcycles = 19; - optional string host = 20; - optional double cost = 21; - - optional string task_queue_name = 22; - optional string task_name = 23; - - optional bool was_loading_request = 24; - optional int64 pending_time = 25; - optional int32 replica_index = 26 [default = -1]; - optional bool finished = 27 [default = true]; - optional bytes clone_key = 28; - - repeated LogLine line = 29; - - optional bool lines_incomplete = 36; - optional bytes app_engine_release = 38; - - optional int32 exit_reason = 30; - optional bool was_throttled_for_time = 31; - optional bool was_throttled_for_requests = 32; - optional int64 throttled_time = 33; - - optional bytes server_name = 34; -} - -message LogModuleVersion { - optional string module_id = 1 [default="default"]; - optional string version_id = 2; -} - -message LogReadRequest { - required string app_id = 1; - repeated string version_id = 2; - repeated LogModuleVersion module_version = 19; - - optional int64 start_time = 3; - optional int64 end_time = 4; - optional LogOffset offset = 5; - repeated bytes request_id = 6; - - optional int32 minimum_log_level = 7; - optional bool include_incomplete = 8; - optional int64 count = 9; - - optional string combined_log_regex = 14; - optional string host_regex = 15; - optional int32 replica_index = 16; - - optional bool include_app_logs = 10; - optional int32 app_logs_per_request = 17; - optional bool include_host = 11; - optional bool include_all = 12; - optional bool cache_iterator = 13; - optional int32 num_shards = 18; -} - -message LogReadResponse { - repeated RequestLog log = 1; - optional LogOffset offset = 2; - optional int64 last_end_time = 3; -} - -message LogUsageRecord { - optional string version_id = 1; - optional int32 start_time = 2; - optional int32 end_time = 3; - optional int64 count = 4; - optional int64 total_size = 5; - optional int32 records = 6; -} - -message LogUsageRequest { - required string app_id = 1; - repeated string version_id = 2; - optional int32 start_time = 3; - optional int32 end_time = 4; - optional uint32 resolution_hours = 5 [default = 1]; - optional bool combine_versions = 6; - optional int32 usage_version = 7; - optional bool versions_only = 8; -} - -message LogUsageResponse { - repeated LogUsageRecord usage = 1; - optional LogUsageRecord summary = 2; -} diff --git a/vendor/google.golang.org/appengine/internal/main.go b/vendor/google.golang.org/appengine/internal/main.go deleted file mode 100644 index afd0ae84..00000000 --- a/vendor/google.golang.org/appengine/internal/main.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build appengine -// +build appengine - -package internal - -import ( - "appengine_internal" -) - -func Main() { - MainPath = "" - appengine_internal.Main() -} diff --git a/vendor/google.golang.org/appengine/internal/main_common.go b/vendor/google.golang.org/appengine/internal/main_common.go deleted file mode 100644 index 357dce4d..00000000 --- a/vendor/google.golang.org/appengine/internal/main_common.go +++ /dev/null @@ -1,7 +0,0 @@ -package internal - -// MainPath stores the file path of the main package. On App Engine Standard -// using Go version 1.9 and below, this will be unset. On App Engine Flex and -// App Engine Standard second-gen (Go 1.11 and above), this will be the -// filepath to package main. -var MainPath string diff --git a/vendor/google.golang.org/appengine/internal/main_vm.go b/vendor/google.golang.org/appengine/internal/main_vm.go deleted file mode 100644 index 86a8caf0..00000000 --- a/vendor/google.golang.org/appengine/internal/main_vm.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -//go:build !appengine -// +build !appengine - -package internal - -import ( - "io" - "log" - "net/http" - "net/url" - "os" - "path/filepath" - "runtime" -) - -func Main() { - MainPath = filepath.Dir(findMainPath()) - installHealthChecker(http.DefaultServeMux) - - port := "8080" - if s := os.Getenv("PORT"); s != "" { - port = s - } - - host := "" - if IsDevAppServer() { - host = "127.0.0.1" - } - if err := http.ListenAndServe(host+":"+port, Middleware(http.DefaultServeMux)); err != nil { - log.Fatalf("http.ListenAndServe: %v", err) - } -} - -// Find the path to package main by looking at the root Caller. -func findMainPath() string { - pc := make([]uintptr, 100) - n := runtime.Callers(2, pc) - frames := runtime.CallersFrames(pc[:n]) - for { - frame, more := frames.Next() - // Tests won't have package main, instead they have testing.tRunner - if frame.Function == "main.main" || frame.Function == "testing.tRunner" { - return frame.File - } - if !more { - break - } - } - return "" -} - -func installHealthChecker(mux *http.ServeMux) { - // If no health check handler has been installed by this point, add a trivial one. - const healthPath = "/_ah/health" - hreq := &http.Request{ - Method: "GET", - URL: &url.URL{ - Path: healthPath, - }, - } - if _, pat := mux.Handler(hreq); pat != healthPath { - mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) { - io.WriteString(w, "ok") - }) - } -} diff --git a/vendor/google.golang.org/appengine/internal/metadata.go b/vendor/google.golang.org/appengine/internal/metadata.go deleted file mode 100644 index c4ba63bb..00000000 --- a/vendor/google.golang.org/appengine/internal/metadata.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package internal - -// This file has code for accessing metadata. -// -// References: -// https://cloud.google.com/compute/docs/metadata - -import ( - "fmt" - "io/ioutil" - "net/http" - "net/url" -) - -const ( - metadataHost = "metadata" - metadataPath = "/computeMetadata/v1/" -) - -var ( - metadataRequestHeaders = http.Header{ - "Metadata-Flavor": []string{"Google"}, - } -) - -// TODO(dsymonds): Do we need to support default values, like Python? -func mustGetMetadata(key string) []byte { - b, err := getMetadata(key) - if err != nil { - panic(fmt.Sprintf("Metadata fetch failed for '%s': %v", key, err)) - } - return b -} - -func getMetadata(key string) ([]byte, error) { - // TODO(dsymonds): May need to use url.Parse to support keys with query args. - req := &http.Request{ - Method: "GET", - URL: &url.URL{ - Scheme: "http", - Host: metadataHost, - Path: metadataPath + key, - }, - Header: metadataRequestHeaders, - Host: metadataHost, - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode) - } - return ioutil.ReadAll(resp.Body) -} diff --git a/vendor/google.golang.org/appengine/internal/net.go b/vendor/google.golang.org/appengine/internal/net.go deleted file mode 100644 index fe429720..00000000 --- a/vendor/google.golang.org/appengine/internal/net.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package internal - -// This file implements a network dialer that limits the number of concurrent connections. -// It is only used for API calls. - -import ( - "log" - "net" - "runtime" - "sync" - "time" -) - -var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable. - -func limitRelease() { - // non-blocking - select { - case <-limitSem: - default: - // This should not normally happen. - log.Print("appengine: unbalanced limitSem release!") - } -} - -func limitDial(network, addr string) (net.Conn, error) { - limitSem <- 1 - - // Dial with a timeout in case the API host is MIA. - // The connection should normally be very fast. - conn, err := net.DialTimeout(network, addr, 10*time.Second) - if err != nil { - limitRelease() - return nil, err - } - lc := &limitConn{Conn: conn} - runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required - return lc, nil -} - -type limitConn struct { - close sync.Once - net.Conn -} - -func (lc *limitConn) Close() error { - defer lc.close.Do(func() { - limitRelease() - runtime.SetFinalizer(lc, nil) - }) - return lc.Conn.Close() -} diff --git a/vendor/google.golang.org/appengine/internal/regen.sh b/vendor/google.golang.org/appengine/internal/regen.sh deleted file mode 100644 index 2fdb546a..00000000 --- a/vendor/google.golang.org/appengine/internal/regen.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -e -# -# This script rebuilds the generated code for the protocol buffers. -# To run this you will need protoc and goprotobuf installed; -# see https://github.com/golang/protobuf for instructions. - -PKG=google.golang.org/appengine - -function die() { - echo 1>&2 $* - exit 1 -} - -# Sanity check that the right tools are accessible. -for tool in go protoc protoc-gen-go; do - q=$(which $tool) || die "didn't find $tool" - echo 1>&2 "$tool: $q" -done - -echo -n 1>&2 "finding package dir... " -pkgdir=$(go list -f '{{.Dir}}' $PKG) -echo 1>&2 $pkgdir -base=$(echo $pkgdir | sed "s,/$PKG\$,,") -echo 1>&2 "base: $base" -cd $base - -# Run protoc once per package. -for dir in $(find $PKG/internal -name '*.proto' | xargs dirname | sort | uniq); do - echo 1>&2 "* $dir" - protoc --go_out=. $dir/*.proto -done - -for f in $(find $PKG/internal -name '*.pb.go'); do - # Remove proto.RegisterEnum calls. - # These cause duplicate registration panics when these packages - # are used on classic App Engine. proto.RegisterEnum only affects - # parsing the text format; we don't care about that. - # https://code.google.com/p/googleappengine/issues/detail?id=11670#c17 - sed -i '/proto.RegisterEnum/d' $f -done diff --git a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go deleted file mode 100644 index 8d782a38..00000000 --- a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go +++ /dev/null @@ -1,361 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google.golang.org/appengine/internal/remote_api/remote_api.proto - -package remote_api - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type RpcError_ErrorCode int32 - -const ( - RpcError_UNKNOWN RpcError_ErrorCode = 0 - RpcError_CALL_NOT_FOUND RpcError_ErrorCode = 1 - RpcError_PARSE_ERROR RpcError_ErrorCode = 2 - RpcError_SECURITY_VIOLATION RpcError_ErrorCode = 3 - RpcError_OVER_QUOTA RpcError_ErrorCode = 4 - RpcError_REQUEST_TOO_LARGE RpcError_ErrorCode = 5 - RpcError_CAPABILITY_DISABLED RpcError_ErrorCode = 6 - RpcError_FEATURE_DISABLED RpcError_ErrorCode = 7 - RpcError_BAD_REQUEST RpcError_ErrorCode = 8 - RpcError_RESPONSE_TOO_LARGE RpcError_ErrorCode = 9 - RpcError_CANCELLED RpcError_ErrorCode = 10 - RpcError_REPLAY_ERROR RpcError_ErrorCode = 11 - RpcError_DEADLINE_EXCEEDED RpcError_ErrorCode = 12 -) - -var RpcError_ErrorCode_name = map[int32]string{ - 0: "UNKNOWN", - 1: "CALL_NOT_FOUND", - 2: "PARSE_ERROR", - 3: "SECURITY_VIOLATION", - 4: "OVER_QUOTA", - 5: "REQUEST_TOO_LARGE", - 6: "CAPABILITY_DISABLED", - 7: "FEATURE_DISABLED", - 8: "BAD_REQUEST", - 9: "RESPONSE_TOO_LARGE", - 10: "CANCELLED", - 11: "REPLAY_ERROR", - 12: "DEADLINE_EXCEEDED", -} -var RpcError_ErrorCode_value = map[string]int32{ - "UNKNOWN": 0, - "CALL_NOT_FOUND": 1, - "PARSE_ERROR": 2, - "SECURITY_VIOLATION": 3, - "OVER_QUOTA": 4, - "REQUEST_TOO_LARGE": 5, - "CAPABILITY_DISABLED": 6, - "FEATURE_DISABLED": 7, - "BAD_REQUEST": 8, - "RESPONSE_TOO_LARGE": 9, - "CANCELLED": 10, - "REPLAY_ERROR": 11, - "DEADLINE_EXCEEDED": 12, -} - -func (x RpcError_ErrorCode) Enum() *RpcError_ErrorCode { - p := new(RpcError_ErrorCode) - *p = x - return p -} -func (x RpcError_ErrorCode) String() string { - return proto.EnumName(RpcError_ErrorCode_name, int32(x)) -} -func (x *RpcError_ErrorCode) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RpcError_ErrorCode_value, data, "RpcError_ErrorCode") - if err != nil { - return err - } - *x = RpcError_ErrorCode(value) - return nil -} -func (RpcError_ErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_remote_api_1978114ec33a273d, []int{2, 0} -} - -type Request struct { - ServiceName *string `protobuf:"bytes,2,req,name=service_name,json=serviceName" json:"service_name,omitempty"` - Method *string `protobuf:"bytes,3,req,name=method" json:"method,omitempty"` - Request []byte `protobuf:"bytes,4,req,name=request" json:"request,omitempty"` - RequestId *string `protobuf:"bytes,5,opt,name=request_id,json=requestId" json:"request_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_remote_api_1978114ec33a273d, []int{0} -} -func (m *Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Request.Unmarshal(m, b) -} -func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Request.Marshal(b, m, deterministic) -} -func (dst *Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_Request.Merge(dst, src) -} -func (m *Request) XXX_Size() int { - return xxx_messageInfo_Request.Size(m) -} -func (m *Request) XXX_DiscardUnknown() { - xxx_messageInfo_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_Request proto.InternalMessageInfo - -func (m *Request) GetServiceName() string { - if m != nil && m.ServiceName != nil { - return *m.ServiceName - } - return "" -} - -func (m *Request) GetMethod() string { - if m != nil && m.Method != nil { - return *m.Method - } - return "" -} - -func (m *Request) GetRequest() []byte { - if m != nil { - return m.Request - } - return nil -} - -func (m *Request) GetRequestId() string { - if m != nil && m.RequestId != nil { - return *m.RequestId - } - return "" -} - -type ApplicationError struct { - Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"` - Detail *string `protobuf:"bytes,2,req,name=detail" json:"detail,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ApplicationError) Reset() { *m = ApplicationError{} } -func (m *ApplicationError) String() string { return proto.CompactTextString(m) } -func (*ApplicationError) ProtoMessage() {} -func (*ApplicationError) Descriptor() ([]byte, []int) { - return fileDescriptor_remote_api_1978114ec33a273d, []int{1} -} -func (m *ApplicationError) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplicationError.Unmarshal(m, b) -} -func (m *ApplicationError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplicationError.Marshal(b, m, deterministic) -} -func (dst *ApplicationError) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplicationError.Merge(dst, src) -} -func (m *ApplicationError) XXX_Size() int { - return xxx_messageInfo_ApplicationError.Size(m) -} -func (m *ApplicationError) XXX_DiscardUnknown() { - xxx_messageInfo_ApplicationError.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplicationError proto.InternalMessageInfo - -func (m *ApplicationError) GetCode() int32 { - if m != nil && m.Code != nil { - return *m.Code - } - return 0 -} - -func (m *ApplicationError) GetDetail() string { - if m != nil && m.Detail != nil { - return *m.Detail - } - return "" -} - -type RpcError struct { - Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"` - Detail *string `protobuf:"bytes,2,opt,name=detail" json:"detail,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RpcError) Reset() { *m = RpcError{} } -func (m *RpcError) String() string { return proto.CompactTextString(m) } -func (*RpcError) ProtoMessage() {} -func (*RpcError) Descriptor() ([]byte, []int) { - return fileDescriptor_remote_api_1978114ec33a273d, []int{2} -} -func (m *RpcError) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RpcError.Unmarshal(m, b) -} -func (m *RpcError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RpcError.Marshal(b, m, deterministic) -} -func (dst *RpcError) XXX_Merge(src proto.Message) { - xxx_messageInfo_RpcError.Merge(dst, src) -} -func (m *RpcError) XXX_Size() int { - return xxx_messageInfo_RpcError.Size(m) -} -func (m *RpcError) XXX_DiscardUnknown() { - xxx_messageInfo_RpcError.DiscardUnknown(m) -} - -var xxx_messageInfo_RpcError proto.InternalMessageInfo - -func (m *RpcError) GetCode() int32 { - if m != nil && m.Code != nil { - return *m.Code - } - return 0 -} - -func (m *RpcError) GetDetail() string { - if m != nil && m.Detail != nil { - return *m.Detail - } - return "" -} - -type Response struct { - Response []byte `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"` - Exception []byte `protobuf:"bytes,2,opt,name=exception" json:"exception,omitempty"` - ApplicationError *ApplicationError `protobuf:"bytes,3,opt,name=application_error,json=applicationError" json:"application_error,omitempty"` - JavaException []byte `protobuf:"bytes,4,opt,name=java_exception,json=javaException" json:"java_exception,omitempty"` - RpcError *RpcError `protobuf:"bytes,5,opt,name=rpc_error,json=rpcError" json:"rpc_error,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_remote_api_1978114ec33a273d, []int{3} -} -func (m *Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Response.Unmarshal(m, b) -} -func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Response.Marshal(b, m, deterministic) -} -func (dst *Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_Response.Merge(dst, src) -} -func (m *Response) XXX_Size() int { - return xxx_messageInfo_Response.Size(m) -} -func (m *Response) XXX_DiscardUnknown() { - xxx_messageInfo_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_Response proto.InternalMessageInfo - -func (m *Response) GetResponse() []byte { - if m != nil { - return m.Response - } - return nil -} - -func (m *Response) GetException() []byte { - if m != nil { - return m.Exception - } - return nil -} - -func (m *Response) GetApplicationError() *ApplicationError { - if m != nil { - return m.ApplicationError - } - return nil -} - -func (m *Response) GetJavaException() []byte { - if m != nil { - return m.JavaException - } - return nil -} - -func (m *Response) GetRpcError() *RpcError { - if m != nil { - return m.RpcError - } - return nil -} - -func init() { - proto.RegisterType((*Request)(nil), "remote_api.Request") - proto.RegisterType((*ApplicationError)(nil), "remote_api.ApplicationError") - proto.RegisterType((*RpcError)(nil), "remote_api.RpcError") - proto.RegisterType((*Response)(nil), "remote_api.Response") -} - -func init() { - proto.RegisterFile("google.golang.org/appengine/internal/remote_api/remote_api.proto", fileDescriptor_remote_api_1978114ec33a273d) -} - -var fileDescriptor_remote_api_1978114ec33a273d = []byte{ - // 531 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x51, 0x6e, 0xd3, 0x40, - 0x10, 0x86, 0xb1, 0x9b, 0x34, 0xf1, 0xc4, 0x2d, 0xdb, 0xa5, 0x14, 0x0b, 0x15, 0x29, 0x44, 0x42, - 0xca, 0x53, 0x2a, 0x38, 0x00, 0x62, 0x63, 0x6f, 0x91, 0x85, 0x65, 0xa7, 0x6b, 0xbb, 0x50, 0x5e, - 0x56, 0x2b, 0x67, 0x65, 0x8c, 0x12, 0xaf, 0xd9, 0x98, 0x8a, 0x17, 0x6e, 0xc0, 0xb5, 0x38, 0x0c, - 0xb7, 0x40, 0x36, 0x6e, 0x63, 0xf5, 0x89, 0xb7, 0x7f, 0x7e, 0x7b, 0xe6, 0x1b, 0xcd, 0xcc, 0xc2, - 0xbb, 0x5c, 0xa9, 0x7c, 0x23, 0x17, 0xb9, 0xda, 0x88, 0x32, 0x5f, 0x28, 0x9d, 0x5f, 0x88, 0xaa, - 0x92, 0x65, 0x5e, 0x94, 0xf2, 0xa2, 0x28, 0x6b, 0xa9, 0x4b, 0xb1, 0xb9, 0xd0, 0x72, 0xab, 0x6a, - 0xc9, 0x45, 0x55, 0xf4, 0xe4, 0xa2, 0xd2, 0xaa, 0x56, 0x18, 0xf6, 0xce, 0xec, 0x27, 0x8c, 0x98, - 0xfc, 0xf6, 0x5d, 0xee, 0x6a, 0xfc, 0x12, 0xec, 0x9d, 0xd4, 0xb7, 0x45, 0x26, 0x79, 0x29, 0xb6, - 0xd2, 0x31, 0xa7, 0xe6, 0xdc, 0x62, 0x93, 0xce, 0x0b, 0xc5, 0x56, 0xe2, 0x33, 0x38, 0xdc, 0xca, - 0xfa, 0x8b, 0x5a, 0x3b, 0x07, 0xed, 0xc7, 0x2e, 0xc2, 0x0e, 0x8c, 0xf4, 0xbf, 0x2a, 0xce, 0x60, - 0x6a, 0xce, 0x6d, 0x76, 0x17, 0xe2, 0x17, 0x00, 0x9d, 0xe4, 0xc5, 0xda, 0x19, 0x4e, 0x8d, 0xb9, - 0xc5, 0xac, 0xce, 0xf1, 0xd7, 0xb3, 0xb7, 0x80, 0x48, 0x55, 0x6d, 0x8a, 0x4c, 0xd4, 0x85, 0x2a, - 0xa9, 0xd6, 0x4a, 0x63, 0x0c, 0x83, 0x4c, 0xad, 0xa5, 0x63, 0x4c, 0xcd, 0xf9, 0x90, 0xb5, 0xba, - 0x01, 0xaf, 0x65, 0x2d, 0x8a, 0x4d, 0xd7, 0x55, 0x17, 0xcd, 0x7e, 0x9b, 0x30, 0x66, 0x55, 0xf6, - 0x7f, 0x89, 0x46, 0x2f, 0xf1, 0x97, 0x09, 0x56, 0x9b, 0xe5, 0x36, 0x7f, 0x4d, 0x60, 0x94, 0x86, - 0x1f, 0xc2, 0xe8, 0x63, 0x88, 0x1e, 0x61, 0x0c, 0xc7, 0x2e, 0x09, 0x02, 0x1e, 0x46, 0x09, 0xbf, - 0x8c, 0xd2, 0xd0, 0x43, 0x06, 0x7e, 0x0c, 0x93, 0x15, 0x61, 0x31, 0xe5, 0x94, 0xb1, 0x88, 0x21, - 0x13, 0x9f, 0x01, 0x8e, 0xa9, 0x9b, 0x32, 0x3f, 0xb9, 0xe1, 0xd7, 0x7e, 0x14, 0x90, 0xc4, 0x8f, - 0x42, 0x74, 0x80, 0x8f, 0x01, 0xa2, 0x6b, 0xca, 0xf8, 0x55, 0x1a, 0x25, 0x04, 0x0d, 0xf0, 0x53, - 0x38, 0x61, 0xf4, 0x2a, 0xa5, 0x71, 0xc2, 0x93, 0x28, 0xe2, 0x01, 0x61, 0xef, 0x29, 0x1a, 0xe2, - 0x67, 0xf0, 0xc4, 0x25, 0x2b, 0xb2, 0xf4, 0x83, 0xa6, 0x80, 0xe7, 0xc7, 0x64, 0x19, 0x50, 0x0f, - 0x1d, 0xe2, 0x53, 0x40, 0x97, 0x94, 0x24, 0x29, 0xa3, 0x7b, 0x77, 0xd4, 0xe0, 0x97, 0xc4, 0xe3, - 0x5d, 0x25, 0x34, 0x6e, 0xf0, 0x8c, 0xc6, 0xab, 0x28, 0x8c, 0x69, 0xaf, 0xae, 0x85, 0x8f, 0xc0, - 0x72, 0x49, 0xe8, 0xd2, 0xa0, 0xc9, 0x03, 0x8c, 0xc0, 0x66, 0x74, 0x15, 0x90, 0x9b, 0xae, 0xef, - 0x49, 0xd3, 0x8f, 0x47, 0x89, 0x17, 0xf8, 0x21, 0xe5, 0xf4, 0x93, 0x4b, 0xa9, 0x47, 0x3d, 0x64, - 0xcf, 0xfe, 0x18, 0x30, 0x66, 0x72, 0x57, 0xa9, 0x72, 0x27, 0xf1, 0x73, 0x18, 0xeb, 0x4e, 0x3b, - 0xc6, 0xd4, 0x98, 0xdb, 0xec, 0x3e, 0xc6, 0xe7, 0x60, 0xc9, 0x1f, 0x99, 0xac, 0x9a, 0x75, 0xb5, - 0x23, 0xb5, 0xd9, 0xde, 0xc0, 0x3e, 0x9c, 0x88, 0xfd, 0x3a, 0xb9, 0x6c, 0x06, 0xec, 0x1c, 0x4c, - 0x8d, 0xf9, 0xe4, 0xcd, 0xf9, 0xa2, 0x77, 0x87, 0x0f, 0x77, 0xce, 0x90, 0x78, 0x78, 0x05, 0xaf, - 0xe0, 0xf8, 0xab, 0xb8, 0x15, 0x7c, 0x4f, 0x1b, 0xb4, 0xb4, 0xa3, 0xc6, 0xa5, 0xf7, 0xc4, 0xd7, - 0x60, 0xe9, 0x2a, 0xeb, 0x48, 0xc3, 0x96, 0x74, 0xda, 0x27, 0xdd, 0x1d, 0x07, 0x1b, 0xeb, 0x4e, - 0x2d, 0xed, 0xcf, 0xbd, 0x07, 0xf0, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xd1, 0x0f, 0x22, 0x4f, - 0x03, 0x00, 0x00, -} diff --git a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto deleted file mode 100644 index f21763a4..00000000 --- a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto2"; -option go_package = "remote_api"; - -package remote_api; - -message Request { - required string service_name = 2; - required string method = 3; - required bytes request = 4; - optional string request_id = 5; -} - -message ApplicationError { - required int32 code = 1; - required string detail = 2; -} - -message RpcError { - enum ErrorCode { - UNKNOWN = 0; - CALL_NOT_FOUND = 1; - PARSE_ERROR = 2; - SECURITY_VIOLATION = 3; - OVER_QUOTA = 4; - REQUEST_TOO_LARGE = 5; - CAPABILITY_DISABLED = 6; - FEATURE_DISABLED = 7; - BAD_REQUEST = 8; - RESPONSE_TOO_LARGE = 9; - CANCELLED = 10; - REPLAY_ERROR = 11; - DEADLINE_EXCEEDED = 12; - } - required int32 code = 1; - optional string detail = 2; -} - -message Response { - optional bytes response = 1; - optional bytes exception = 2; - optional ApplicationError application_error = 3; - optional bytes java_exception = 4; - optional RpcError rpc_error = 5; -} diff --git a/vendor/google.golang.org/appengine/internal/transaction.go b/vendor/google.golang.org/appengine/internal/transaction.go deleted file mode 100644 index 2ae8ab9f..00000000 --- a/vendor/google.golang.org/appengine/internal/transaction.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2014 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package internal - -// This file implements hooks for applying datastore transactions. - -import ( - "context" - "errors" - "reflect" - - "github.com/golang/protobuf/proto" - - basepb "google.golang.org/appengine/internal/base" - pb "google.golang.org/appengine/internal/datastore" -) - -var transactionSetters = make(map[reflect.Type]reflect.Value) - -// RegisterTransactionSetter registers a function that sets transaction information -// in a protocol buffer message. f should be a function with two arguments, -// the first being a protocol buffer type, and the second being *datastore.Transaction. -func RegisterTransactionSetter(f interface{}) { - v := reflect.ValueOf(f) - transactionSetters[v.Type().In(0)] = v -} - -// applyTransaction applies the transaction t to message pb -// by using the relevant setter passed to RegisterTransactionSetter. -func applyTransaction(pb proto.Message, t *pb.Transaction) { - v := reflect.ValueOf(pb) - if f, ok := transactionSetters[v.Type()]; ok { - f.Call([]reflect.Value{v, reflect.ValueOf(t)}) - } -} - -var transactionKey = "used for *Transaction" - -func transactionFromContext(ctx context.Context) *transaction { - t, _ := ctx.Value(&transactionKey).(*transaction) - return t -} - -func withTransaction(ctx context.Context, t *transaction) context.Context { - return context.WithValue(ctx, &transactionKey, t) -} - -type transaction struct { - transaction pb.Transaction - finished bool -} - -var ErrConcurrentTransaction = errors.New("internal: concurrent transaction") - -func RunTransactionOnce(c context.Context, f func(context.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) { - if transactionFromContext(c) != nil { - return nil, errors.New("nested transactions are not supported") - } - - // Begin the transaction. - t := &transaction{} - req := &pb.BeginTransactionRequest{ - App: proto.String(FullyQualifiedAppID(c)), - } - if xg { - req.AllowMultipleEg = proto.Bool(true) - } - if previousTransaction != nil { - req.PreviousTransaction = previousTransaction - } - if readOnly { - req.Mode = pb.BeginTransactionRequest_READ_ONLY.Enum() - } else { - req.Mode = pb.BeginTransactionRequest_READ_WRITE.Enum() - } - if err := Call(c, "datastore_v3", "BeginTransaction", req, &t.transaction); err != nil { - return nil, err - } - - // Call f, rolling back the transaction if f returns a non-nil error, or panics. - // The panic is not recovered. - defer func() { - if t.finished { - return - } - t.finished = true - // Ignore the error return value, since we are already returning a non-nil - // error (or we're panicking). - Call(c, "datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{}) - }() - if err := f(withTransaction(c, t)); err != nil { - return &t.transaction, err - } - t.finished = true - - // Commit the transaction. - res := &pb.CommitResponse{} - err := Call(c, "datastore_v3", "Commit", &t.transaction, res) - if ae, ok := err.(*APIError); ok { - /* TODO: restore this conditional - if appengine.IsDevAppServer() { - */ - // The Python Dev AppServer raises an ApplicationError with error code 2 (which is - // Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.". - if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." { - return &t.transaction, ErrConcurrentTransaction - } - if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) { - return &t.transaction, ErrConcurrentTransaction - } - } - return &t.transaction, err -} diff --git a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go deleted file mode 100644 index 5f727750..00000000 --- a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go +++ /dev/null @@ -1,527 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto - -package urlfetch - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type URLFetchServiceError_ErrorCode int32 - -const ( - URLFetchServiceError_OK URLFetchServiceError_ErrorCode = 0 - URLFetchServiceError_INVALID_URL URLFetchServiceError_ErrorCode = 1 - URLFetchServiceError_FETCH_ERROR URLFetchServiceError_ErrorCode = 2 - URLFetchServiceError_UNSPECIFIED_ERROR URLFetchServiceError_ErrorCode = 3 - URLFetchServiceError_RESPONSE_TOO_LARGE URLFetchServiceError_ErrorCode = 4 - URLFetchServiceError_DEADLINE_EXCEEDED URLFetchServiceError_ErrorCode = 5 - URLFetchServiceError_SSL_CERTIFICATE_ERROR URLFetchServiceError_ErrorCode = 6 - URLFetchServiceError_DNS_ERROR URLFetchServiceError_ErrorCode = 7 - URLFetchServiceError_CLOSED URLFetchServiceError_ErrorCode = 8 - URLFetchServiceError_INTERNAL_TRANSIENT_ERROR URLFetchServiceError_ErrorCode = 9 - URLFetchServiceError_TOO_MANY_REDIRECTS URLFetchServiceError_ErrorCode = 10 - URLFetchServiceError_MALFORMED_REPLY URLFetchServiceError_ErrorCode = 11 - URLFetchServiceError_CONNECTION_ERROR URLFetchServiceError_ErrorCode = 12 -) - -var URLFetchServiceError_ErrorCode_name = map[int32]string{ - 0: "OK", - 1: "INVALID_URL", - 2: "FETCH_ERROR", - 3: "UNSPECIFIED_ERROR", - 4: "RESPONSE_TOO_LARGE", - 5: "DEADLINE_EXCEEDED", - 6: "SSL_CERTIFICATE_ERROR", - 7: "DNS_ERROR", - 8: "CLOSED", - 9: "INTERNAL_TRANSIENT_ERROR", - 10: "TOO_MANY_REDIRECTS", - 11: "MALFORMED_REPLY", - 12: "CONNECTION_ERROR", -} -var URLFetchServiceError_ErrorCode_value = map[string]int32{ - "OK": 0, - "INVALID_URL": 1, - "FETCH_ERROR": 2, - "UNSPECIFIED_ERROR": 3, - "RESPONSE_TOO_LARGE": 4, - "DEADLINE_EXCEEDED": 5, - "SSL_CERTIFICATE_ERROR": 6, - "DNS_ERROR": 7, - "CLOSED": 8, - "INTERNAL_TRANSIENT_ERROR": 9, - "TOO_MANY_REDIRECTS": 10, - "MALFORMED_REPLY": 11, - "CONNECTION_ERROR": 12, -} - -func (x URLFetchServiceError_ErrorCode) Enum() *URLFetchServiceError_ErrorCode { - p := new(URLFetchServiceError_ErrorCode) - *p = x - return p -} -func (x URLFetchServiceError_ErrorCode) String() string { - return proto.EnumName(URLFetchServiceError_ErrorCode_name, int32(x)) -} -func (x *URLFetchServiceError_ErrorCode) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(URLFetchServiceError_ErrorCode_value, data, "URLFetchServiceError_ErrorCode") - if err != nil { - return err - } - *x = URLFetchServiceError_ErrorCode(value) - return nil -} -func (URLFetchServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0, 0} -} - -type URLFetchRequest_RequestMethod int32 - -const ( - URLFetchRequest_GET URLFetchRequest_RequestMethod = 1 - URLFetchRequest_POST URLFetchRequest_RequestMethod = 2 - URLFetchRequest_HEAD URLFetchRequest_RequestMethod = 3 - URLFetchRequest_PUT URLFetchRequest_RequestMethod = 4 - URLFetchRequest_DELETE URLFetchRequest_RequestMethod = 5 - URLFetchRequest_PATCH URLFetchRequest_RequestMethod = 6 -) - -var URLFetchRequest_RequestMethod_name = map[int32]string{ - 1: "GET", - 2: "POST", - 3: "HEAD", - 4: "PUT", - 5: "DELETE", - 6: "PATCH", -} -var URLFetchRequest_RequestMethod_value = map[string]int32{ - "GET": 1, - "POST": 2, - "HEAD": 3, - "PUT": 4, - "DELETE": 5, - "PATCH": 6, -} - -func (x URLFetchRequest_RequestMethod) Enum() *URLFetchRequest_RequestMethod { - p := new(URLFetchRequest_RequestMethod) - *p = x - return p -} -func (x URLFetchRequest_RequestMethod) String() string { - return proto.EnumName(URLFetchRequest_RequestMethod_name, int32(x)) -} -func (x *URLFetchRequest_RequestMethod) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(URLFetchRequest_RequestMethod_value, data, "URLFetchRequest_RequestMethod") - if err != nil { - return err - } - *x = URLFetchRequest_RequestMethod(value) - return nil -} -func (URLFetchRequest_RequestMethod) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0} -} - -type URLFetchServiceError struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *URLFetchServiceError) Reset() { *m = URLFetchServiceError{} } -func (m *URLFetchServiceError) String() string { return proto.CompactTextString(m) } -func (*URLFetchServiceError) ProtoMessage() {} -func (*URLFetchServiceError) Descriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0} -} -func (m *URLFetchServiceError) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_URLFetchServiceError.Unmarshal(m, b) -} -func (m *URLFetchServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_URLFetchServiceError.Marshal(b, m, deterministic) -} -func (dst *URLFetchServiceError) XXX_Merge(src proto.Message) { - xxx_messageInfo_URLFetchServiceError.Merge(dst, src) -} -func (m *URLFetchServiceError) XXX_Size() int { - return xxx_messageInfo_URLFetchServiceError.Size(m) -} -func (m *URLFetchServiceError) XXX_DiscardUnknown() { - xxx_messageInfo_URLFetchServiceError.DiscardUnknown(m) -} - -var xxx_messageInfo_URLFetchServiceError proto.InternalMessageInfo - -type URLFetchRequest struct { - Method *URLFetchRequest_RequestMethod `protobuf:"varint,1,req,name=Method,enum=appengine.URLFetchRequest_RequestMethod" json:"Method,omitempty"` - Url *string `protobuf:"bytes,2,req,name=Url" json:"Url,omitempty"` - Header []*URLFetchRequest_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"` - Payload []byte `protobuf:"bytes,6,opt,name=Payload" json:"Payload,omitempty"` - FollowRedirects *bool `protobuf:"varint,7,opt,name=FollowRedirects,def=1" json:"FollowRedirects,omitempty"` - Deadline *float64 `protobuf:"fixed64,8,opt,name=Deadline" json:"Deadline,omitempty"` - MustValidateServerCertificate *bool `protobuf:"varint,9,opt,name=MustValidateServerCertificate,def=1" json:"MustValidateServerCertificate,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *URLFetchRequest) Reset() { *m = URLFetchRequest{} } -func (m *URLFetchRequest) String() string { return proto.CompactTextString(m) } -func (*URLFetchRequest) ProtoMessage() {} -func (*URLFetchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1} -} -func (m *URLFetchRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_URLFetchRequest.Unmarshal(m, b) -} -func (m *URLFetchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_URLFetchRequest.Marshal(b, m, deterministic) -} -func (dst *URLFetchRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_URLFetchRequest.Merge(dst, src) -} -func (m *URLFetchRequest) XXX_Size() int { - return xxx_messageInfo_URLFetchRequest.Size(m) -} -func (m *URLFetchRequest) XXX_DiscardUnknown() { - xxx_messageInfo_URLFetchRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_URLFetchRequest proto.InternalMessageInfo - -const Default_URLFetchRequest_FollowRedirects bool = true -const Default_URLFetchRequest_MustValidateServerCertificate bool = true - -func (m *URLFetchRequest) GetMethod() URLFetchRequest_RequestMethod { - if m != nil && m.Method != nil { - return *m.Method - } - return URLFetchRequest_GET -} - -func (m *URLFetchRequest) GetUrl() string { - if m != nil && m.Url != nil { - return *m.Url - } - return "" -} - -func (m *URLFetchRequest) GetHeader() []*URLFetchRequest_Header { - if m != nil { - return m.Header - } - return nil -} - -func (m *URLFetchRequest) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -func (m *URLFetchRequest) GetFollowRedirects() bool { - if m != nil && m.FollowRedirects != nil { - return *m.FollowRedirects - } - return Default_URLFetchRequest_FollowRedirects -} - -func (m *URLFetchRequest) GetDeadline() float64 { - if m != nil && m.Deadline != nil { - return *m.Deadline - } - return 0 -} - -func (m *URLFetchRequest) GetMustValidateServerCertificate() bool { - if m != nil && m.MustValidateServerCertificate != nil { - return *m.MustValidateServerCertificate - } - return Default_URLFetchRequest_MustValidateServerCertificate -} - -type URLFetchRequest_Header struct { - Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"` - Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *URLFetchRequest_Header) Reset() { *m = URLFetchRequest_Header{} } -func (m *URLFetchRequest_Header) String() string { return proto.CompactTextString(m) } -func (*URLFetchRequest_Header) ProtoMessage() {} -func (*URLFetchRequest_Header) Descriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0} -} -func (m *URLFetchRequest_Header) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_URLFetchRequest_Header.Unmarshal(m, b) -} -func (m *URLFetchRequest_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_URLFetchRequest_Header.Marshal(b, m, deterministic) -} -func (dst *URLFetchRequest_Header) XXX_Merge(src proto.Message) { - xxx_messageInfo_URLFetchRequest_Header.Merge(dst, src) -} -func (m *URLFetchRequest_Header) XXX_Size() int { - return xxx_messageInfo_URLFetchRequest_Header.Size(m) -} -func (m *URLFetchRequest_Header) XXX_DiscardUnknown() { - xxx_messageInfo_URLFetchRequest_Header.DiscardUnknown(m) -} - -var xxx_messageInfo_URLFetchRequest_Header proto.InternalMessageInfo - -func (m *URLFetchRequest_Header) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *URLFetchRequest_Header) GetValue() string { - if m != nil && m.Value != nil { - return *m.Value - } - return "" -} - -type URLFetchResponse struct { - Content []byte `protobuf:"bytes,1,opt,name=Content" json:"Content,omitempty"` - StatusCode *int32 `protobuf:"varint,2,req,name=StatusCode" json:"StatusCode,omitempty"` - Header []*URLFetchResponse_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"` - ContentWasTruncated *bool `protobuf:"varint,6,opt,name=ContentWasTruncated,def=0" json:"ContentWasTruncated,omitempty"` - ExternalBytesSent *int64 `protobuf:"varint,7,opt,name=ExternalBytesSent" json:"ExternalBytesSent,omitempty"` - ExternalBytesReceived *int64 `protobuf:"varint,8,opt,name=ExternalBytesReceived" json:"ExternalBytesReceived,omitempty"` - FinalUrl *string `protobuf:"bytes,9,opt,name=FinalUrl" json:"FinalUrl,omitempty"` - ApiCpuMilliseconds *int64 `protobuf:"varint,10,opt,name=ApiCpuMilliseconds,def=0" json:"ApiCpuMilliseconds,omitempty"` - ApiBytesSent *int64 `protobuf:"varint,11,opt,name=ApiBytesSent,def=0" json:"ApiBytesSent,omitempty"` - ApiBytesReceived *int64 `protobuf:"varint,12,opt,name=ApiBytesReceived,def=0" json:"ApiBytesReceived,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *URLFetchResponse) Reset() { *m = URLFetchResponse{} } -func (m *URLFetchResponse) String() string { return proto.CompactTextString(m) } -func (*URLFetchResponse) ProtoMessage() {} -func (*URLFetchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2} -} -func (m *URLFetchResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_URLFetchResponse.Unmarshal(m, b) -} -func (m *URLFetchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_URLFetchResponse.Marshal(b, m, deterministic) -} -func (dst *URLFetchResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_URLFetchResponse.Merge(dst, src) -} -func (m *URLFetchResponse) XXX_Size() int { - return xxx_messageInfo_URLFetchResponse.Size(m) -} -func (m *URLFetchResponse) XXX_DiscardUnknown() { - xxx_messageInfo_URLFetchResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_URLFetchResponse proto.InternalMessageInfo - -const Default_URLFetchResponse_ContentWasTruncated bool = false -const Default_URLFetchResponse_ApiCpuMilliseconds int64 = 0 -const Default_URLFetchResponse_ApiBytesSent int64 = 0 -const Default_URLFetchResponse_ApiBytesReceived int64 = 0 - -func (m *URLFetchResponse) GetContent() []byte { - if m != nil { - return m.Content - } - return nil -} - -func (m *URLFetchResponse) GetStatusCode() int32 { - if m != nil && m.StatusCode != nil { - return *m.StatusCode - } - return 0 -} - -func (m *URLFetchResponse) GetHeader() []*URLFetchResponse_Header { - if m != nil { - return m.Header - } - return nil -} - -func (m *URLFetchResponse) GetContentWasTruncated() bool { - if m != nil && m.ContentWasTruncated != nil { - return *m.ContentWasTruncated - } - return Default_URLFetchResponse_ContentWasTruncated -} - -func (m *URLFetchResponse) GetExternalBytesSent() int64 { - if m != nil && m.ExternalBytesSent != nil { - return *m.ExternalBytesSent - } - return 0 -} - -func (m *URLFetchResponse) GetExternalBytesReceived() int64 { - if m != nil && m.ExternalBytesReceived != nil { - return *m.ExternalBytesReceived - } - return 0 -} - -func (m *URLFetchResponse) GetFinalUrl() string { - if m != nil && m.FinalUrl != nil { - return *m.FinalUrl - } - return "" -} - -func (m *URLFetchResponse) GetApiCpuMilliseconds() int64 { - if m != nil && m.ApiCpuMilliseconds != nil { - return *m.ApiCpuMilliseconds - } - return Default_URLFetchResponse_ApiCpuMilliseconds -} - -func (m *URLFetchResponse) GetApiBytesSent() int64 { - if m != nil && m.ApiBytesSent != nil { - return *m.ApiBytesSent - } - return Default_URLFetchResponse_ApiBytesSent -} - -func (m *URLFetchResponse) GetApiBytesReceived() int64 { - if m != nil && m.ApiBytesReceived != nil { - return *m.ApiBytesReceived - } - return Default_URLFetchResponse_ApiBytesReceived -} - -type URLFetchResponse_Header struct { - Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"` - Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *URLFetchResponse_Header) Reset() { *m = URLFetchResponse_Header{} } -func (m *URLFetchResponse_Header) String() string { return proto.CompactTextString(m) } -func (*URLFetchResponse_Header) ProtoMessage() {} -func (*URLFetchResponse_Header) Descriptor() ([]byte, []int) { - return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2, 0} -} -func (m *URLFetchResponse_Header) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_URLFetchResponse_Header.Unmarshal(m, b) -} -func (m *URLFetchResponse_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_URLFetchResponse_Header.Marshal(b, m, deterministic) -} -func (dst *URLFetchResponse_Header) XXX_Merge(src proto.Message) { - xxx_messageInfo_URLFetchResponse_Header.Merge(dst, src) -} -func (m *URLFetchResponse_Header) XXX_Size() int { - return xxx_messageInfo_URLFetchResponse_Header.Size(m) -} -func (m *URLFetchResponse_Header) XXX_DiscardUnknown() { - xxx_messageInfo_URLFetchResponse_Header.DiscardUnknown(m) -} - -var xxx_messageInfo_URLFetchResponse_Header proto.InternalMessageInfo - -func (m *URLFetchResponse_Header) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *URLFetchResponse_Header) GetValue() string { - if m != nil && m.Value != nil { - return *m.Value - } - return "" -} - -func init() { - proto.RegisterType((*URLFetchServiceError)(nil), "appengine.URLFetchServiceError") - proto.RegisterType((*URLFetchRequest)(nil), "appengine.URLFetchRequest") - proto.RegisterType((*URLFetchRequest_Header)(nil), "appengine.URLFetchRequest.Header") - proto.RegisterType((*URLFetchResponse)(nil), "appengine.URLFetchResponse") - proto.RegisterType((*URLFetchResponse_Header)(nil), "appengine.URLFetchResponse.Header") -} - -func init() { - proto.RegisterFile("google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto", fileDescriptor_urlfetch_service_b245a7065f33bced) -} - -var fileDescriptor_urlfetch_service_b245a7065f33bced = []byte{ - // 770 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0xe3, 0x54, - 0x10, 0xc6, 0x76, 0x7e, 0xa7, 0x5d, 0x7a, 0x76, 0xb6, 0x45, 0x66, 0xb5, 0xa0, 0x10, 0x09, 0x29, - 0x17, 0x90, 0x2e, 0x2b, 0x24, 0x44, 0xaf, 0x70, 0xed, 0x93, 0xad, 0xa9, 0x63, 0x47, 0xc7, 0x4e, - 0x61, 0xb9, 0xb1, 0xac, 0x78, 0x9a, 0x5a, 0xb2, 0xec, 0x60, 0x9f, 0x2c, 0xf4, 0x35, 0x78, 0x0d, - 0xde, 0x87, 0xa7, 0xe1, 0x02, 0x9d, 0xc4, 0xc9, 0x6e, 0xbb, 0xd1, 0x4a, 0x5c, 0x65, 0xe6, 0x9b, - 0xef, 0xcc, 0x99, 0x7c, 0xdf, 0xf8, 0x80, 0xb3, 0x2c, 0xcb, 0x65, 0x4e, 0xe3, 0x65, 0x99, 0x27, - 0xc5, 0x72, 0x5c, 0x56, 0xcb, 0xf3, 0x64, 0xb5, 0xa2, 0x62, 0x99, 0x15, 0x74, 0x9e, 0x15, 0x92, - 0xaa, 0x22, 0xc9, 0xcf, 0xd7, 0x55, 0x7e, 0x4b, 0x72, 0x71, 0xb7, 0x0f, 0xe2, 0x9a, 0xaa, 0xb7, - 0xd9, 0x82, 0xc6, 0xab, 0xaa, 0x94, 0x25, 0xf6, 0xf7, 0x67, 0x86, 0x7f, 0xeb, 0x70, 0x3a, 0x17, - 0xde, 0x44, 0xb1, 0xc2, 0x2d, 0x89, 0x57, 0x55, 0x59, 0x0d, 0xff, 0xd2, 0xa1, 0xbf, 0x89, 0xec, - 0x32, 0x25, 0xec, 0x80, 0x1e, 0x5c, 0xb3, 0x4f, 0xf0, 0x04, 0x8e, 0x5c, 0xff, 0xc6, 0xf2, 0x5c, - 0x27, 0x9e, 0x0b, 0x8f, 0x69, 0x0a, 0x98, 0xf0, 0xc8, 0xbe, 0x8a, 0xb9, 0x10, 0x81, 0x60, 0x3a, - 0x9e, 0xc1, 0xd3, 0xb9, 0x1f, 0xce, 0xb8, 0xed, 0x4e, 0x5c, 0xee, 0x34, 0xb0, 0x81, 0x9f, 0x01, - 0x0a, 0x1e, 0xce, 0x02, 0x3f, 0xe4, 0x71, 0x14, 0x04, 0xb1, 0x67, 0x89, 0xd7, 0x9c, 0xb5, 0x14, - 0xdd, 0xe1, 0x96, 0xe3, 0xb9, 0x3e, 0x8f, 0xf9, 0xaf, 0x36, 0xe7, 0x0e, 0x77, 0x58, 0x1b, 0x3f, - 0x87, 0xb3, 0x30, 0xf4, 0x62, 0x9b, 0x8b, 0xc8, 0x9d, 0xb8, 0xb6, 0x15, 0xf1, 0xa6, 0x53, 0x07, - 0x9f, 0x40, 0xdf, 0xf1, 0xc3, 0x26, 0xed, 0x22, 0x40, 0xc7, 0xf6, 0x82, 0x90, 0x3b, 0xac, 0x87, - 0x2f, 0xc0, 0x74, 0xfd, 0x88, 0x0b, 0xdf, 0xf2, 0xe2, 0x48, 0x58, 0x7e, 0xe8, 0x72, 0x3f, 0x6a, - 0x98, 0x7d, 0x35, 0x82, 0xba, 0x79, 0x6a, 0xf9, 0x6f, 0x62, 0xc1, 0x1d, 0x57, 0x70, 0x3b, 0x0a, - 0x19, 0xe0, 0x33, 0x38, 0x99, 0x5a, 0xde, 0x24, 0x10, 0x53, 0xee, 0xc4, 0x82, 0xcf, 0xbc, 0x37, - 0xec, 0x08, 0x4f, 0x81, 0xd9, 0x81, 0xef, 0x73, 0x3b, 0x72, 0x03, 0xbf, 0x69, 0x71, 0x3c, 0xfc, - 0xc7, 0x80, 0x93, 0x9d, 0x5a, 0x82, 0x7e, 0x5f, 0x53, 0x2d, 0xf1, 0x27, 0xe8, 0x4c, 0x49, 0xde, - 0x95, 0xa9, 0xa9, 0x0d, 0xf4, 0xd1, 0xa7, 0xaf, 0x46, 0xe3, 0xbd, 0xba, 0xe3, 0x47, 0xdc, 0x71, - 0xf3, 0xbb, 0xe5, 0x8b, 0xe6, 0x1c, 0x32, 0x30, 0xe6, 0x55, 0x6e, 0xea, 0x03, 0x7d, 0xd4, 0x17, - 0x2a, 0xc4, 0x1f, 0xa1, 0x73, 0x47, 0x49, 0x4a, 0x95, 0x69, 0x0c, 0x8c, 0x11, 0xbc, 0xfa, 0xea, - 0x23, 0x3d, 0xaf, 0x36, 0x44, 0xd1, 0x1c, 0xc0, 0x17, 0xd0, 0x9d, 0x25, 0xf7, 0x79, 0x99, 0xa4, - 0x66, 0x67, 0xa0, 0x8d, 0x8e, 0x2f, 0xf5, 0x9e, 0x26, 0x76, 0x10, 0x8e, 0xe1, 0x64, 0x52, 0xe6, - 0x79, 0xf9, 0x87, 0xa0, 0x34, 0xab, 0x68, 0x21, 0x6b, 0xb3, 0x3b, 0xd0, 0x46, 0xbd, 0x8b, 0x96, - 0xac, 0xd6, 0x24, 0x1e, 0x17, 0xf1, 0x39, 0xf4, 0x1c, 0x4a, 0xd2, 0x3c, 0x2b, 0xc8, 0xec, 0x0d, - 0xb4, 0x91, 0x26, 0xf6, 0x39, 0xfe, 0x0c, 0x5f, 0x4c, 0xd7, 0xb5, 0xbc, 0x49, 0xf2, 0x2c, 0x4d, - 0x24, 0xa9, 0xed, 0xa1, 0xca, 0xa6, 0x4a, 0x66, 0xb7, 0xd9, 0x22, 0x91, 0x64, 0xf6, 0xdf, 0xeb, - 0xfc, 0x71, 0xea, 0xf3, 0x97, 0xd0, 0xd9, 0xfe, 0x0f, 0x25, 0xc6, 0x35, 0xdd, 0x9b, 0xad, 0xad, - 0x18, 0xd7, 0x74, 0x8f, 0xa7, 0xd0, 0xbe, 0x49, 0xf2, 0x35, 0x99, 0xed, 0x0d, 0xb6, 0x4d, 0x86, - 0x1e, 0x3c, 0x79, 0xa0, 0x26, 0x76, 0xc1, 0x78, 0xcd, 0x23, 0xa6, 0x61, 0x0f, 0x5a, 0xb3, 0x20, - 0x8c, 0x98, 0xae, 0xa2, 0x2b, 0x6e, 0x39, 0xcc, 0x50, 0xc5, 0xd9, 0x3c, 0x62, 0x2d, 0xb5, 0x2e, - 0x0e, 0xf7, 0x78, 0xc4, 0x59, 0x1b, 0xfb, 0xd0, 0x9e, 0x59, 0x91, 0x7d, 0xc5, 0x3a, 0xc3, 0x7f, - 0x0d, 0x60, 0xef, 0x84, 0xad, 0x57, 0x65, 0x51, 0x13, 0x9a, 0xd0, 0xb5, 0xcb, 0x42, 0x52, 0x21, - 0x4d, 0x4d, 0x49, 0x29, 0x76, 0x29, 0x7e, 0x09, 0x10, 0xca, 0x44, 0xae, 0x6b, 0xf5, 0x71, 0x6c, - 0x8c, 0x6b, 0x8b, 0xf7, 0x10, 0xbc, 0x78, 0xe4, 0xdf, 0xf0, 0xa0, 0x7f, 0xdb, 0x6b, 0x1e, 0x1b, - 0xf8, 0x03, 0x3c, 0x6b, 0xae, 0xf9, 0x25, 0xa9, 0xa3, 0x6a, 0x5d, 0x28, 0x81, 0xb6, 0x66, 0xf6, - 0x2e, 0xda, 0xb7, 0x49, 0x5e, 0x93, 0x38, 0xc4, 0xc0, 0x6f, 0xe0, 0x29, 0xff, 0x73, 0xfb, 0x02, - 0x5c, 0xde, 0x4b, 0xaa, 0x43, 0x35, 0xb8, 0x72, 0xd7, 0x10, 0x1f, 0x16, 0xf0, 0x7b, 0x38, 0x7b, - 0x00, 0x0a, 0x5a, 0x50, 0xf6, 0x96, 0xd2, 0x8d, 0xcd, 0x86, 0x38, 0x5c, 0x54, 0xfb, 0x30, 0xc9, - 0x8a, 0x24, 0x57, 0xfb, 0xaa, 0xec, 0xed, 0x8b, 0x7d, 0x8e, 0xdf, 0x01, 0x5a, 0xab, 0xcc, 0x5e, - 0xad, 0xa7, 0x59, 0x9e, 0x67, 0x35, 0x2d, 0xca, 0x22, 0xad, 0x4d, 0x50, 0xed, 0x2e, 0xb4, 0x97, - 0xe2, 0x40, 0x11, 0xbf, 0x86, 0x63, 0x6b, 0x95, 0xbd, 0x9b, 0xf6, 0x68, 0x47, 0x7e, 0x00, 0xe3, - 0xb7, 0xc0, 0x76, 0xf9, 0x7e, 0xcc, 0xe3, 0x1d, 0xf5, 0x83, 0xd2, 0xff, 0x5f, 0xa6, 0x4b, 0xf8, - 0xad, 0xb7, 0x7b, 0x2a, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x9f, 0x6d, 0x24, 0x63, 0x05, - 0x00, 0x00, -} diff --git a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto deleted file mode 100644 index f695edf6..00000000 --- a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +++ /dev/null @@ -1,64 +0,0 @@ -syntax = "proto2"; -option go_package = "urlfetch"; - -package appengine; - -message URLFetchServiceError { - enum ErrorCode { - OK = 0; - INVALID_URL = 1; - FETCH_ERROR = 2; - UNSPECIFIED_ERROR = 3; - RESPONSE_TOO_LARGE = 4; - DEADLINE_EXCEEDED = 5; - SSL_CERTIFICATE_ERROR = 6; - DNS_ERROR = 7; - CLOSED = 8; - INTERNAL_TRANSIENT_ERROR = 9; - TOO_MANY_REDIRECTS = 10; - MALFORMED_REPLY = 11; - CONNECTION_ERROR = 12; - } -} - -message URLFetchRequest { - enum RequestMethod { - GET = 1; - POST = 2; - HEAD = 3; - PUT = 4; - DELETE = 5; - PATCH = 6; - } - required RequestMethod Method = 1; - required string Url = 2; - repeated group Header = 3 { - required string Key = 4; - required string Value = 5; - } - optional bytes Payload = 6 [ctype=CORD]; - - optional bool FollowRedirects = 7 [default=true]; - - optional double Deadline = 8; - - optional bool MustValidateServerCertificate = 9 [default=true]; -} - -message URLFetchResponse { - optional bytes Content = 1; - required int32 StatusCode = 2; - repeated group Header = 3 { - required string Key = 4; - required string Value = 5; - } - optional bool ContentWasTruncated = 6 [default=false]; - optional int64 ExternalBytesSent = 7; - optional int64 ExternalBytesReceived = 8; - - optional string FinalUrl = 9; - - optional int64 ApiCpuMilliseconds = 10 [default=0]; - optional int64 ApiBytesSent = 11 [default=0]; - optional int64 ApiBytesReceived = 12 [default=0]; -} diff --git a/vendor/google.golang.org/appengine/urlfetch/urlfetch.go b/vendor/google.golang.org/appengine/urlfetch/urlfetch.go deleted file mode 100644 index 6c0d7241..00000000 --- a/vendor/google.golang.org/appengine/urlfetch/urlfetch.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// Package urlfetch provides an http.RoundTripper implementation -// for fetching URLs via App Engine's urlfetch service. -package urlfetch // import "google.golang.org/appengine/urlfetch" - -import ( - "context" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - - "google.golang.org/appengine/internal" - pb "google.golang.org/appengine/internal/urlfetch" -) - -// Transport is an implementation of http.RoundTripper for -// App Engine. Users should generally create an http.Client using -// this transport and use the Client rather than using this transport -// directly. -type Transport struct { - Context context.Context - - // Controls whether the application checks the validity of SSL certificates - // over HTTPS connections. A value of false (the default) instructs the - // application to send a request to the server only if the certificate is - // valid and signed by a trusted certificate authority (CA), and also - // includes a hostname that matches the certificate. A value of true - // instructs the application to perform no certificate validation. - AllowInvalidServerCertificate bool -} - -// Verify statically that *Transport implements http.RoundTripper. -var _ http.RoundTripper = (*Transport)(nil) - -// Client returns an *http.Client using a default urlfetch Transport. This -// client will check the validity of SSL certificates. -// -// Any deadline of the provided context will be used for requests through this client. -// If the client does not have a deadline, then an App Engine default of 60 second is used. -func Client(ctx context.Context) *http.Client { - return &http.Client{ - Transport: &Transport{ - Context: ctx, - }, - } -} - -type bodyReader struct { - content []byte - truncated bool - closed bool -} - -// ErrTruncatedBody is the error returned after the final Read() from a -// response's Body if the body has been truncated by App Engine's proxy. -var ErrTruncatedBody = errors.New("urlfetch: truncated body") - -func statusCodeToText(code int) string { - if t := http.StatusText(code); t != "" { - return t - } - return strconv.Itoa(code) -} - -func (br *bodyReader) Read(p []byte) (n int, err error) { - if br.closed { - if br.truncated { - return 0, ErrTruncatedBody - } - return 0, io.EOF - } - n = copy(p, br.content) - if n > 0 { - br.content = br.content[n:] - return - } - if br.truncated { - br.closed = true - return 0, ErrTruncatedBody - } - return 0, io.EOF -} - -func (br *bodyReader) Close() error { - br.closed = true - br.content = nil - return nil -} - -// A map of the URL Fetch-accepted methods that take a request body. -var methodAcceptsRequestBody = map[string]bool{ - "POST": true, - "PUT": true, - "PATCH": true, -} - -// urlString returns a valid string given a URL. This function is necessary because -// the String method of URL doesn't correctly handle URLs with non-empty Opaque values. -// See http://code.google.com/p/go/issues/detail?id=4860. -func urlString(u *url.URL) string { - if u.Opaque == "" || strings.HasPrefix(u.Opaque, "//") { - return u.String() - } - aux := *u - aux.Opaque = "//" + aux.Host + aux.Opaque - return aux.String() -} - -// RoundTrip issues a single HTTP request and returns its response. Per the -// http.RoundTripper interface, RoundTrip only returns an error if there -// was an unsupported request or the URL Fetch proxy fails. -// Note that HTTP response codes such as 5xx, 403, 404, etc are not -// errors as far as the transport is concerned and will be returned -// with err set to nil. -func (t *Transport) RoundTrip(req *http.Request) (res *http.Response, err error) { - methNum, ok := pb.URLFetchRequest_RequestMethod_value[req.Method] - if !ok { - return nil, fmt.Errorf("urlfetch: unsupported HTTP method %q", req.Method) - } - - method := pb.URLFetchRequest_RequestMethod(methNum) - - freq := &pb.URLFetchRequest{ - Method: &method, - Url: proto.String(urlString(req.URL)), - FollowRedirects: proto.Bool(false), // http.Client's responsibility - MustValidateServerCertificate: proto.Bool(!t.AllowInvalidServerCertificate), - } - if deadline, ok := t.Context.Deadline(); ok { - freq.Deadline = proto.Float64(deadline.Sub(time.Now()).Seconds()) - } - - for k, vals := range req.Header { - for _, val := range vals { - freq.Header = append(freq.Header, &pb.URLFetchRequest_Header{ - Key: proto.String(k), - Value: proto.String(val), - }) - } - } - if methodAcceptsRequestBody[req.Method] && req.Body != nil { - // Avoid a []byte copy if req.Body has a Bytes method. - switch b := req.Body.(type) { - case interface { - Bytes() []byte - }: - freq.Payload = b.Bytes() - default: - freq.Payload, err = ioutil.ReadAll(req.Body) - if err != nil { - return nil, err - } - } - } - - fres := &pb.URLFetchResponse{} - if err := internal.Call(t.Context, "urlfetch", "Fetch", freq, fres); err != nil { - return nil, err - } - - res = &http.Response{} - res.StatusCode = int(*fres.StatusCode) - res.Status = fmt.Sprintf("%d %s", res.StatusCode, statusCodeToText(res.StatusCode)) - res.Header = make(http.Header) - res.Request = req - - // Faked: - res.ProtoMajor = 1 - res.ProtoMinor = 1 - res.Proto = "HTTP/1.1" - res.Close = true - - for _, h := range fres.Header { - hkey := http.CanonicalHeaderKey(*h.Key) - hval := *h.Value - if hkey == "Content-Length" { - // Will get filled in below for all but HEAD requests. - if req.Method == "HEAD" { - res.ContentLength, _ = strconv.ParseInt(hval, 10, 64) - } - continue - } - res.Header.Add(hkey, hval) - } - - if req.Method != "HEAD" { - res.ContentLength = int64(len(fres.Content)) - } - - truncated := fres.GetContentWasTruncated() - res.Body = &bodyReader{content: fres.Content, truncated: truncated} - return -} - -func init() { - internal.RegisterErrorCodeMap("urlfetch", pb.URLFetchServiceError_ErrorCode_name) - internal.RegisterTimeoutErrorCode("urlfetch", int32(pb.URLFetchServiceError_DEADLINE_EXCEEDED)) -} diff --git a/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go b/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go index 3543268f..e7d3805e 100644 --- a/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go @@ -1,4 +1,4 @@ -// Copyright 2023 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.21.9 +// protoc v4.24.4 // source: google/api/httpbody.proto package httpbody diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go index 7bd161e4..3e562182 100644 --- a/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.21.9 +// protoc v4.24.4 // source: google/rpc/error_details.proto package errdetails diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go index a6b50818..6ad1b1c1 100644 --- a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.21.9 +// protoc v4.24.4 // source: google/rpc/status.proto package status diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md index 608aa6e1..0854d298 100644 --- a/vendor/google.golang.org/grpc/CONTRIBUTING.md +++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md @@ -66,7 +66,7 @@ How to get your contributions merged smoothly and quickly. - **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on. - - `VET_SKIP_PROTO=1 ./vet.sh` to catch vet errors + - `./scripts/vet.sh` to catch vet errors - `go test -cpu 1,4 -timeout 7m ./...` to run the tests - `go test -race -cpu 1,4 -timeout 7m ./...` to run tests in race mode diff --git a/vendor/google.golang.org/grpc/MAINTAINERS.md b/vendor/google.golang.org/grpc/MAINTAINERS.md index c6672c0a..6a8a0778 100644 --- a/vendor/google.golang.org/grpc/MAINTAINERS.md +++ b/vendor/google.golang.org/grpc/MAINTAINERS.md @@ -9,6 +9,7 @@ for general contribution guidelines. ## Maintainers (in alphabetical order) +- [atollena](https://github.com/atollena), Datadog, Inc. - [cesarghali](https://github.com/cesarghali), Google LLC - [dfawley](https://github.com/dfawley), Google LLC - [easwars](https://github.com/easwars), Google LLC diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile index 1f896092..be38384f 100644 --- a/vendor/google.golang.org/grpc/Makefile +++ b/vendor/google.golang.org/grpc/Makefile @@ -30,17 +30,20 @@ testdeps: GO111MODULE=on go get -d -v -t google.golang.org/grpc/... vet: vetdeps - ./vet.sh + ./scripts/vet.sh vetdeps: - ./vet.sh -install + ./scripts/vet.sh -install .PHONY: \ all \ build \ clean \ + deps \ proto \ test \ + testsubmodule \ testrace \ + testdeps \ vet \ vetdeps diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index ab0fbb79..b572707c 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -10,7 +10,7 @@ RPC framework that puts mobile and HTTP/2 first. For more information see the ## Prerequisites -- **[Go][]**: any one of the **three latest major** [releases][go-releases]. +- **[Go][]**: any one of the **two latest major** [releases][go-releases]. ## Installation diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go similarity index 74% rename from vendor/google.golang.org/grpc/pickfirst.go rename to vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go index e3ea42ba..07527603 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go @@ -16,26 +16,36 @@ * */ -package grpc +// Package pickfirst contains the pick_first load balancing policy. +package pickfirst import ( "encoding/json" "errors" "fmt" + "math/rand" "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal" internalgrpclog "google.golang.org/grpc/internal/grpclog" - "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" ) +func init() { + balancer.Register(pickfirstBuilder{}) + internal.ShuffleAddressListForTesting = func(n int, swap func(i, j int)) { rand.Shuffle(n, swap) } +} + +var logger = grpclog.Component("pick-first-lb") + const ( - // PickFirstBalancerName is the name of the pick_first balancer. - PickFirstBalancerName = "pick_first" - logPrefix = "[pick-first-lb %p] " + // Name is the name of the pick_first balancer. + Name = "pick_first" + logPrefix = "[pick-first-lb %p] " ) type pickfirstBuilder struct{} @@ -47,14 +57,14 @@ func (pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) } func (pickfirstBuilder) Name() string { - return PickFirstBalancerName + return Name } type pfConfig struct { serviceconfig.LoadBalancingConfig `json:"-"` // If set to true, instructs the LB policy to shuffle the order of the list - // of addresses received from the name resolver before attempting to + // of endpoints received from the name resolver before attempting to // connect to them. ShuffleAddressList bool `json:"shuffleAddressList"` } @@ -93,9 +103,14 @@ func (b *pickfirstBalancer) ResolverError(err error) { }) } +type Shuffler interface { + ShuffleAddressListForTesting(n int, swap func(i, j int)) +} + +func ShuffleAddressListForTesting(n int, swap func(i, j int)) { rand.Shuffle(n, swap) } + func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error { - addrs := state.ResolverState.Addresses - if len(addrs) == 0 { + if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 { // The resolver reported an empty address list. Treat it like an error by // calling b.ResolverError. if b.subConn != nil { @@ -107,22 +122,49 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState b.ResolverError(errors.New("produced zero addresses")) return balancer.ErrBadResolverState } - // We don't have to guard this block with the env var because ParseConfig // already does so. cfg, ok := state.BalancerConfig.(pfConfig) if state.BalancerConfig != nil && !ok { return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v", state.BalancerConfig, state.BalancerConfig) } - if cfg.ShuffleAddressList { - addrs = append([]resolver.Address{}, addrs...) - grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) - } if b.logger.V(2) { b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState)) } + var addrs []resolver.Address + if endpoints := state.ResolverState.Endpoints; len(endpoints) != 0 { + // Perform the optional shuffling described in gRFC A62. The shuffling will + // change the order of endpoints but not touch the order of the addresses + // within each endpoint. - A61 + if cfg.ShuffleAddressList { + endpoints = append([]resolver.Endpoint{}, endpoints...) + internal.ShuffleAddressListForTesting.(func(int, func(int, int)))(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) + } + + // "Flatten the list by concatenating the ordered list of addresses for each + // of the endpoints, in order." - A61 + for _, endpoint := range endpoints { + // "In the flattened list, interleave addresses from the two address + // families, as per RFC-8304 section 4." - A61 + // TODO: support the above language. + addrs = append(addrs, endpoint.Addresses...) + } + } else { + // Endpoints not set, process addresses until we migrate resolver + // emissions fully to Endpoints. The top channel does wrap emitted + // addresses with endpoints, however some balancers such as weighted + // target do not forwarrd the corresponding correct endpoints down/split + // endpoints properly. Once all balancers correctly forward endpoints + // down, can delete this else conditional. + addrs = state.ResolverState.Addresses + if cfg.ShuffleAddressList { + addrs = append([]resolver.Address{}, addrs...) + rand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) + } + } + if b.subConn != nil { b.cc.UpdateAddresses(b.subConn, addrs) return nil diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index f7031ad2..260255d3 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -22,12 +22,12 @@ package roundrobin import ( + "math/rand" "sync/atomic" "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/base" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal/grpcrand" ) // Name is the name of round_robin balancer. @@ -60,7 +60,7 @@ func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker { // Start at a random index, as the same RR balancer rebuilds a new // picker when SubConn states change, and we don't want to apply excess // load to the first server in the list. - next: uint32(grpcrand.Intn(len(scs))), + next: uint32(rand.Intn(len(scs))), } } diff --git a/vendor/google.golang.org/grpc/balancer_wrapper.go b/vendor/google.golang.org/grpc/balancer_wrapper.go index af39b8a4..4161fdf4 100644 --- a/vendor/google.golang.org/grpc/balancer_wrapper.go +++ b/vendor/google.golang.org/grpc/balancer_wrapper.go @@ -198,6 +198,10 @@ func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resol func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { ccb.cc.mu.Lock() defer ccb.cc.mu.Unlock() + if ccb.cc.conns == nil { + // The CC has been closed; ignore this update. + return + } ccb.mu.Lock() if ccb.closed { diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index 856c75dd..63c639e4 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v4.25.2 // source: grpc/binlog/v1/binarylog.proto diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index c7f26071..423be7b4 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -31,13 +31,13 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/base" + "google.golang.org/grpc/balancer/pickfirst" "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/idle" - "google.golang.org/grpc/internal/pretty" iresolver "google.golang.org/grpc/internal/resolver" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" @@ -73,6 +73,8 @@ var ( // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default // service config. invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid" + // PickFirstBalancerName is the name of the pick_first balancer. + PickFirstBalancerName = pickfirst.Name ) // The following errors are returned from Dial and DialContext @@ -121,8 +123,9 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires // https://github.com/grpc/grpc/blob/master/doc/naming.md. e.g. to use dns // resolver, a "dns:///" prefix should be applied to the target. // -// The DialOptions returned by WithBlock, WithTimeout, and -// WithReturnConnectionError are ignored by this function. +// The DialOptions returned by WithBlock, WithTimeout, +// WithReturnConnectionError, and FailOnNonTempDialError are ignored by this +// function. func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ target: target, @@ -152,6 +155,16 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) for _, opt := range opts { opt.apply(&cc.dopts) } + + // Determine the resolver to use. + if err := cc.initParsedTargetAndResolverBuilder(); err != nil { + return nil, err + } + + for _, opt := range globalPerTargetDialOptions { + opt.DialOptionForTarget(cc.parsedTarget.URL).apply(&cc.dopts) + } + chainUnaryClientInterceptors(cc) chainStreamClientInterceptors(cc) @@ -160,7 +173,7 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) } if cc.dopts.defaultServiceConfigRawJSON != nil { - scpr := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON) + scpr := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON, cc.dopts.maxCallAttempts) if scpr.Err != nil { return nil, fmt.Errorf("%s: %v", invalidDefaultServiceConfigErrPrefix, scpr.Err) } @@ -168,25 +181,16 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) } cc.mkp = cc.dopts.copts.KeepaliveParams - // Register ClientConn with channelz. - cc.channelzRegistration(target) - - // TODO: Ideally it should be impossible to error from this function after - // channelz registration. This will require removing some channelz logs - // from the following functions that can error. Errors can be returned to - // the user, and successful logs can be emitted here, after the checks have - // passed and channelz is subsequently registered. - - // Determine the resolver to use. - if err := cc.parseTargetAndFindResolver(); err != nil { - channelz.RemoveEntry(cc.channelz.ID) - return nil, err - } - if err = cc.determineAuthority(); err != nil { - channelz.RemoveEntry(cc.channelz.ID) + if err = cc.initAuthority(); err != nil { return nil, err } + // Register ClientConn with channelz. Note that this is only done after + // channel creation cannot fail. + cc.channelzRegistration(target) + channelz.Infof(logger, cc.channelz, "parsed dial target is: %#v", cc.parsedTarget) + channelz.Infof(logger, cc.channelz, "Channel authority set to %q", cc.authority) + cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz) cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers) @@ -196,6 +200,8 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) } // Dial calls DialContext(context.Background(), target, opts...). +// +// Deprecated: use NewClient instead. Will be supported throughout 1.x. func Dial(target string, opts ...DialOption) (*ClientConn, error) { return DialContext(context.Background(), target, opts...) } @@ -209,6 +215,8 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) { // "passthrough" for backward compatibility. This distinction should not matter // to most users, but could matter to legacy users that specify a custom dialer // and expect it to receive the target string directly. +// +// Deprecated: use NewClient instead. Will be supported throughout 1.x. func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { // At the end of this method, we kick the channel out of idle, rather than // waiting for the first rpc. @@ -583,11 +591,11 @@ type ClientConn struct { // The following are initialized at dial time, and are read-only after that. target string // User's dial target. - parsedTarget resolver.Target // See parseTargetAndFindResolver(). - authority string // See determineAuthority(). + parsedTarget resolver.Target // See initParsedTargetAndResolverBuilder(). + authority string // See initAuthority(). dopts dialOptions // Default and user specified dial options. channelz *channelz.Channel // Channelz object. - resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). + resolverBuilder resolver.Builder // See initParsedTargetAndResolverBuilder(). idlenessMgr *idle.Manager // The following provide their own synchronization, and therefore don't @@ -688,8 +696,7 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error { var emptyServiceConfig *ServiceConfig func init() { - balancer.Register(pickfirstBuilder{}) - cfg := parseServiceConfig("{}") + cfg := parseServiceConfig("{}", defaultMaxCallAttempts) if cfg.Err != nil { panic(fmt.Sprintf("impossible error parsing empty service config: %v", cfg.Err)) } @@ -838,6 +845,9 @@ func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer. stateChan: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) + // Start with our address set to the first address; this may be updated if + // we connect to different addresses. + ac.channelz.ChannelMetrics.Target.Store(&addrs[0].Addr) channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ Desc: "Subchannel created", @@ -929,10 +939,14 @@ func equalAddresses(a, b []resolver.Address) bool { // updateAddrs updates ac.addrs with the new addresses list and handles active // connections or connection attempts. func (ac *addrConn) updateAddrs(addrs []resolver.Address) { - ac.mu.Lock() - channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs curAddr: %v, addrs: %v", pretty.ToJSON(ac.curAddr), pretty.ToJSON(addrs)) - addrs = copyAddressesWithoutBalancerAttributes(addrs) + limit := len(addrs) + if limit > 5 { + limit = 5 + } + channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs addrs (%d of %d): %v", limit, len(addrs), addrs[:limit]) + + ac.mu.Lock() if equalAddresses(ac.addrs, addrs) { ac.mu.Unlock() return @@ -1167,6 +1181,10 @@ type addrConn struct { // is received, transport is closed, ac has been torn down). transport transport.ClientTransport // The current transport. + // This mutex is used on the RPC path, so its usage should be minimized as + // much as possible. + // TODO: Find a lock-free way to retrieve the transport and state from the + // addrConn. mu sync.Mutex curAddr resolver.Address // The current address. addrs []resolver.Address // All addresses that the resolver resolved to. @@ -1292,6 +1310,7 @@ func (ac *addrConn) resetTransport() { func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, connectDeadline time.Time) error { var firstConnErr error for _, addr := range addrs { + ac.channelz.ChannelMetrics.Target.Store(&addr.Addr) if ctx.Err() != nil { return errConnClosing } @@ -1657,22 +1676,19 @@ func (cc *ClientConn) connectionError() error { return cc.lastConnectionError } -// parseTargetAndFindResolver parses the user's dial target and stores the -// parsed target in `cc.parsedTarget`. +// initParsedTargetAndResolverBuilder parses the user's dial target and stores +// the parsed target in `cc.parsedTarget`. // // The resolver to use is determined based on the scheme in the parsed target // and the same is stored in `cc.resolverBuilder`. // // Doesn't grab cc.mu as this method is expected to be called only at Dial time. -func (cc *ClientConn) parseTargetAndFindResolver() error { - channelz.Infof(logger, cc.channelz, "original dial target is: %q", cc.target) +func (cc *ClientConn) initParsedTargetAndResolverBuilder() error { + logger.Infof("original dial target is: %q", cc.target) var rb resolver.Builder parsedTarget, err := parseTarget(cc.target) - if err != nil { - channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", cc.target, err) - } else { - channelz.Infof(logger, cc.channelz, "parsed dial target is: %#v", parsedTarget) + if err == nil { rb = cc.getResolver(parsedTarget.URL.Scheme) if rb != nil { cc.parsedTarget = parsedTarget @@ -1691,15 +1707,12 @@ func (cc *ClientConn) parseTargetAndFindResolver() error { defScheme = resolver.GetDefaultScheme() } - channelz.Infof(logger, cc.channelz, "fallback to scheme %q", defScheme) canonicalTarget := defScheme + ":///" + cc.target parsedTarget, err = parseTarget(canonicalTarget) if err != nil { - channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", canonicalTarget, err) return err } - channelz.Infof(logger, cc.channelz, "parsed dial target is: %+v", parsedTarget) rb = cc.getResolver(parsedTarget.URL.Scheme) if rb == nil { return fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) @@ -1739,7 +1752,7 @@ func encodeAuthority(authority string) string { return false case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // Subdelim characters return false - case ':', '[', ']', '@': // Authority related delimeters + case ':', '[', ']', '@': // Authority related delimiters return false } // Everything else must be escaped. @@ -1789,7 +1802,7 @@ func encodeAuthority(authority string) string { // credentials do not match the authority configured through the dial option. // // Doesn't grab cc.mu as this method is expected to be called only at Dial time. -func (cc *ClientConn) determineAuthority() error { +func (cc *ClientConn) initAuthority() error { dopts := cc.dopts // Historically, we had two options for users to specify the serverName or // authority for a channel. One was through the transport credentials @@ -1822,6 +1835,5 @@ func (cc *ClientConn) determineAuthority() error { } else { cc.authority = encodeAuthority(endpoint) } - channelz.Infof(logger, cc.channelz, "Channel authority set to %q", cc.authority) return nil } diff --git a/vendor/google.golang.org/grpc/codegen.sh b/vendor/google.golang.org/grpc/codegen.sh deleted file mode 100644 index 4cdc6ba7..00000000 --- a/vendor/google.golang.org/grpc/codegen.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# This script serves as an example to demonstrate how to generate the gRPC-Go -# interface and the related messages from .proto file. -# -# It assumes the installation of i) Google proto buffer compiler at -# https://github.com/google/protobuf (after v2.6.1) and ii) the Go codegen -# plugin at https://github.com/golang/protobuf (after 2015-02-20). If you have -# not, please install them first. -# -# We recommend running this script at $GOPATH/src. -# -# If this is not what you need, feel free to make your own scripts. Again, this -# script is for demonstration purpose. -# -proto=$1 -protoc --go_out=plugins=grpc:. $proto diff --git a/vendor/google.golang.org/grpc/codes/codes.go b/vendor/google.golang.org/grpc/codes/codes.go index 08476ad1..0b42c302 100644 --- a/vendor/google.golang.org/grpc/codes/codes.go +++ b/vendor/google.golang.org/grpc/codes/codes.go @@ -235,7 +235,7 @@ func (c *Code) UnmarshalJSON(b []byte) error { if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil { if ci >= _maxCode { - return fmt.Errorf("invalid code: %q", ci) + return fmt.Errorf("invalid code: %d", ci) } *c = Code(ci) diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index f6b55c68..665e790b 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -30,7 +30,7 @@ import ( "google.golang.org/grpc/attributes" icredentials "google.golang.org/grpc/internal/credentials" - "google.golang.org/protobuf/protoadapt" + "google.golang.org/protobuf/proto" ) // PerRPCCredentials defines the common interface for the credentials which need to @@ -237,7 +237,7 @@ func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo { } // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one. -// It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method +// It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility. // // This API is experimental. @@ -287,5 +287,5 @@ type ChannelzSecurityValue interface { type OtherChannelzSecurityValue struct { ChannelzSecurityValue Name string - Value protoadapt.MessageV1 + Value proto.Message } diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go index 5dafd34e..41143585 100644 --- a/vendor/google.golang.org/grpc/credentials/tls.go +++ b/vendor/google.golang.org/grpc/credentials/tls.go @@ -27,9 +27,13 @@ import ( "net/url" "os" + "google.golang.org/grpc/grpclog" credinternal "google.golang.org/grpc/internal/credentials" + "google.golang.org/grpc/internal/envconfig" ) +var logger = grpclog.Component("credentials") + // TLSInfo contains the auth information for a TLS authenticated connection. // It implements the AuthInfo interface. type TLSInfo struct { @@ -112,6 +116,22 @@ func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawCon conn.Close() return nil, nil, ctx.Err() } + + // The negotiated protocol can be either of the following: + // 1. h2: When the server supports ALPN. Only HTTP/2 can be negotiated since + // it is the only protocol advertised by the client during the handshake. + // The tls library ensures that the server chooses a protocol advertised + // by the client. + // 2. "" (empty string): If the server doesn't support ALPN. ALPN is a requirement + // for using HTTP/2 over TLS. We can terminate the connection immediately. + np := conn.ConnectionState().NegotiatedProtocol + if np == "" { + if envconfig.EnforceALPNEnabled { + conn.Close() + return nil, nil, fmt.Errorf("credentials: cannot check peer: missing selected ALPN property") + } + logger.Warningf("Allowing TLS connection to server %q with ALPN disabled. TLS connections to servers with ALPN disabled will be disallowed in future grpc-go releases", cfg.ServerName) + } tlsInfo := TLSInfo{ State: conn.ConnectionState(), CommonAuthInfo: CommonAuthInfo{ @@ -131,8 +151,20 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) conn.Close() return nil, nil, err } + cs := conn.ConnectionState() + // The negotiated application protocol can be empty only if the client doesn't + // support ALPN. In such cases, we can close the connection since ALPN is required + // for using HTTP/2 over TLS. + if cs.NegotiatedProtocol == "" { + if envconfig.EnforceALPNEnabled { + conn.Close() + return nil, nil, fmt.Errorf("credentials: cannot check peer: missing selected ALPN property") + } else if logger.V(2) { + logger.Info("Allowing TLS connection from client with ALPN disabled. TLS connections with ALPN disabled will be disallowed in future grpc-go releases") + } + } tlsInfo := TLSInfo{ - State: conn.ConnectionState(), + State: cs, CommonAuthInfo: CommonAuthInfo{ SecurityLevel: PrivacyAndIntegrity, }, diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 40249322..f5453d48 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -21,6 +21,7 @@ package grpc import ( "context" "net" + "net/url" "time" "google.golang.org/grpc/backoff" @@ -36,6 +37,11 @@ import ( "google.golang.org/grpc/stats" ) +const ( + // https://github.com/grpc/proposal/blob/master/A6-client-retries.md#limits-on-retries-and-hedges + defaultMaxCallAttempts = 5 +) + func init() { internal.AddGlobalDialOptions = func(opt ...DialOption) { globalDialOptions = append(globalDialOptions, opt...) @@ -43,6 +49,14 @@ func init() { internal.ClearGlobalDialOptions = func() { globalDialOptions = nil } + internal.AddGlobalPerTargetDialOptions = func(opt any) { + if ptdo, ok := opt.(perTargetDialOption); ok { + globalPerTargetDialOptions = append(globalPerTargetDialOptions, ptdo) + } + } + internal.ClearGlobalPerTargetDialOptions = func() { + globalPerTargetDialOptions = nil + } internal.WithBinaryLogger = withBinaryLogger internal.JoinDialOptions = newJoinDialOption internal.DisableGlobalDialOptions = newDisableGlobalDialOptions @@ -80,6 +94,7 @@ type dialOptions struct { idleTimeout time.Duration recvBufferPool SharedBufferPool defaultScheme string + maxCallAttempts int } // DialOption configures how we set up the connection. @@ -89,6 +104,19 @@ type DialOption interface { var globalDialOptions []DialOption +// perTargetDialOption takes a parsed target and returns a dial option to apply. +// +// This gets called after NewClient() parses the target, and allows per target +// configuration set through a returned DialOption. The DialOption will not take +// effect if specifies a resolver builder, as that Dial Option is factored in +// while parsing target. +type perTargetDialOption interface { + // DialOption returns a Dial Option to apply. + DialOptionForTarget(parsedTarget url.URL) DialOption +} + +var globalPerTargetDialOptions []perTargetDialOption + // EmptyDialOption does not alter the dial configuration. It can be embedded in // another structure to build custom dial options. // @@ -300,6 +328,9 @@ func withBackoff(bs internalbackoff.Strategy) DialOption { // // Use of this feature is not recommended. For more information, please see: // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md +// +// Deprecated: this DialOption is not supported by NewClient. +// Will be supported throughout 1.x. func WithBlock() DialOption { return newFuncDialOption(func(o *dialOptions) { o.block = true @@ -314,10 +345,8 @@ func WithBlock() DialOption { // Use of this feature is not recommended. For more information, please see: // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md // -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Deprecated: this DialOption is not supported by NewClient. +// Will be supported throughout 1.x. func WithReturnConnectionError() DialOption { return newFuncDialOption(func(o *dialOptions) { o.block = true @@ -387,8 +416,8 @@ func WithCredentialsBundle(b credentials.Bundle) DialOption { // WithTimeout returns a DialOption that configures a timeout for dialing a // ClientConn initially. This is valid if and only if WithBlock() is present. // -// Deprecated: use DialContext instead of Dial and context.WithTimeout -// instead. Will be supported throughout 1.x. +// Deprecated: this DialOption is not supported by NewClient. +// Will be supported throughout 1.x. func WithTimeout(d time.Duration) DialOption { return newFuncDialOption(func(o *dialOptions) { o.timeout = d @@ -470,9 +499,8 @@ func withBinaryLogger(bl binarylog.Logger) DialOption { // Use of this feature is not recommended. For more information, please see: // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md // -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// Deprecated: this DialOption is not supported by NewClient. +// This API may be changed or removed in a // later release. func FailOnNonTempDialError(f bool) DialOption { return newFuncDialOption(func(o *dialOptions) { @@ -601,12 +629,22 @@ func WithDisableRetry() DialOption { }) } +// MaxHeaderListSizeDialOption is a DialOption that specifies the maximum +// (uncompressed) size of header list that the client is prepared to accept. +type MaxHeaderListSizeDialOption struct { + MaxHeaderListSize uint32 +} + +func (o MaxHeaderListSizeDialOption) apply(do *dialOptions) { + do.copts.MaxHeaderListSize = &o.MaxHeaderListSize +} + // WithMaxHeaderListSize returns a DialOption that specifies the maximum // (uncompressed) size of header list that the client is prepared to accept. func WithMaxHeaderListSize(s uint32) DialOption { - return newFuncDialOption(func(o *dialOptions) { - o.copts.MaxHeaderListSize = &s - }) + return MaxHeaderListSizeDialOption{ + MaxHeaderListSize: s, + } } // WithDisableHealthCheck disables the LB channel health checking for all @@ -645,10 +683,11 @@ func defaultDialOptions() dialOptions { idleTimeout: 30 * time.Minute, recvBufferPool: nopBufferPool{}, defaultScheme: "dns", + maxCallAttempts: defaultMaxCallAttempts, } } -// withGetMinConnectDeadline specifies the function that clientconn uses to +// withMinConnectDeadline specifies the function that clientconn uses to // get minConnectDeadline. This can be used to make connection attempts happen // faster/slower. // @@ -702,6 +741,23 @@ func WithIdleTimeout(d time.Duration) DialOption { }) } +// WithMaxCallAttempts returns a DialOption that configures the maximum number +// of attempts per call (including retries and hedging) using the channel. +// Service owners may specify a higher value for these parameters, but higher +// values will be treated as equal to the maximum value by the client +// implementation. This mitigates security concerns related to the service +// config being transferred to the client via DNS. +// +// A value of 5 will be used if this dial option is not set or n < 2. +func WithMaxCallAttempts(n int) DialOption { + return newFuncDialOption(func(o *dialOptions) { + if n < 2 { + n = defaultMaxCallAttempts + } + o.maxCallAttempts = n + }) +} + // WithRecvBufferPool returns a DialOption that configures the ClientConn // to use the provided shared buffer pool for parsing incoming messages. Depending // on the application's workload, this could result in reduced memory allocation. diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go index 5bf880d4..38b88350 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v4.25.2 // source: grpc/health/v1/health.proto diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go index 4c46c098..51b736ba 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 +// - protoc-gen-go-grpc v1.4.0 // - protoc v4.25.2 // source: grpc/health/v1/health.proto @@ -32,8 +32,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( Health_Check_FullMethodName = "/grpc.health.v1.Health/Check" @@ -43,6 +43,10 @@ const ( // HealthClient is the client API for Health service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Health is gRPC's mechanism for checking whether a server is able to handle +// RPCs. Its semantics are documented in +// https://github.com/grpc/grpc/blob/master/doc/health-checking.md. type HealthClient interface { // Check gets the health of the specified service. If the requested service // is unknown, the call will fail with status NOT_FOUND. If the caller does @@ -81,8 +85,9 @@ func NewHealthClient(cc grpc.ClientConnInterface) HealthClient { } func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(HealthCheckResponse) - err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -90,11 +95,12 @@ func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts . } func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) { - stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &healthWatchClient{stream} + x := &healthWatchClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -124,6 +130,10 @@ func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) { // HealthServer is the server API for Health service. // All implementations should embed UnimplementedHealthServer // for forward compatibility +// +// Health is gRPC's mechanism for checking whether a server is able to handle +// RPCs. Its semantics are documented in +// https://github.com/grpc/grpc/blob/master/doc/health-checking.md. type HealthServer interface { // Check gets the health of the specified service. If the requested service // is unknown, the call will fail with status NOT_FOUND. If the caller does @@ -198,7 +208,7 @@ func _Health_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { if err := stream.RecvMsg(m); err != nil { return err } - return srv.(HealthServer).Watch(m, &healthWatchServer{stream}) + return srv.(HealthServer).Watch(m, &healthWatchServer{ServerStream: stream}) } type Health_WatchServer interface { diff --git a/vendor/google.golang.org/grpc/internal/backoff/backoff.go b/vendor/google.golang.org/grpc/internal/backoff/backoff.go index fed1c011..b15cf482 100644 --- a/vendor/google.golang.org/grpc/internal/backoff/backoff.go +++ b/vendor/google.golang.org/grpc/internal/backoff/backoff.go @@ -25,10 +25,10 @@ package backoff import ( "context" "errors" + "math/rand" "time" grpcbackoff "google.golang.org/grpc/backoff" - "google.golang.org/grpc/internal/grpcrand" ) // Strategy defines the methodology for backing off after a grpc connection @@ -67,7 +67,7 @@ func (bc Exponential) Backoff(retries int) time.Duration { } // Randomize backoff delays so that if a cluster of requests start at // the same time, they won't operate in lockstep. - backoff *= 1 + bc.Config.Jitter*(grpcrand.Float64()*2-1) + backoff *= 1 + bc.Config.Jitter*(rand.Float64()*2-1) if backoff < 0 { return 0 } diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go index 6bf7f873..13821a92 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go @@ -75,7 +75,6 @@ func ParseConfig(cfg json.RawMessage) (serviceconfig.LoadBalancingConfig, error) if err != nil { return nil, fmt.Errorf("error parsing config for policy %q: %v", name, err) } - return &lbConfig{childBuilder: builder, childConfig: cfg}, nil } diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go index 45d5e50e..73bb4c4e 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go @@ -169,7 +169,6 @@ func (gsb *Balancer) latestBalancer() *balancerWrapper { func (gsb *Balancer) UpdateClientConnState(state balancer.ClientConnState) error { // The resolver data is only relevant to the most recent LB Policy. balToUpdate := gsb.latestBalancer() - gsbCfg, ok := state.BalancerConfig.(*lbConfig) if ok { // Switch to the child in the config unless it is already active. diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index e8456a77..aa4505a8 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -65,7 +65,7 @@ type TruncatingMethodLogger struct { callID uint64 idWithinCallGen *callIDGenerator - sink Sink // TODO(blog): make this plugable. + sink Sink // TODO(blog): make this pluggable. } // NewTruncatingMethodLogger returns a new truncating method logger. @@ -80,7 +80,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { callID: idGen.next(), idWithinCallGen: &callIDGenerator{}, - sink: DefaultSink, // TODO(blog): make it plugable. + sink: DefaultSink, // TODO(blog): make it pluggable. } } @@ -397,7 +397,7 @@ func metadataKeyOmit(key string) bool { switch key { case "lb-token", ":path", ":authority", "content-encoding", "content-type", "user-agent", "te": return true - case "grpc-trace-bin": // grpc-trace-bin is special because it's visiable to users. + case "grpc-trace-bin": // grpc-trace-bin is special because it's visible to users. return false } return strings.HasPrefix(key, "grpc-") diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 685a3cb4..d9064871 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -28,9 +28,6 @@ import ( var ( // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). TXTErrIgnore = boolFromEnv("GRPC_GO_IGNORE_TXT_ERRORS", true) - // AdvertiseCompressors is set if registered compressor should be advertised - // ("GRPC_GO_ADVERTISE_COMPRESSORS" is not "false"). - AdvertiseCompressors = boolFromEnv("GRPC_GO_ADVERTISE_COMPRESSORS", true) // RingHashCap indicates the maximum ring size which defaults to 4096 // entries but may be overridden by setting the environment variable // "GRPC_RING_HASH_CAP". This does not override the default bounds @@ -43,6 +40,12 @@ var ( // ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS // handshakes that can be performed. ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100) + // EnforceALPNEnabled is set if TLS connections to servers with ALPN disabled + // should be rejected. The HTTP/2 protocol requires ALPN to be enabled, this + // option is present for backward compatibility. This option may be overridden + // by setting the environment variable "GRPC_ENFORCE_ALPN_ENABLED" to "true" + // or "false". + EnforceALPNEnabled = boolFromEnv("GRPC_ENFORCE_ALPN_ENABLED", false) ) func boolFromEnv(envVar string, def bool) bool { diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go deleted file mode 100644 index 0126d6b5..00000000 --- a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go +++ /dev/null @@ -1,100 +0,0 @@ -//go:build !go1.21 - -// TODO: when this file is deleted (after Go 1.20 support is dropped), delete -// all of grpcrand and call the rand package directly. - -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed 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 grpcrand implements math/rand functions in a concurrent-safe way -// with a global random source, independent of math/rand's global source. -package grpcrand - -import ( - "math/rand" - "sync" - "time" -) - -var ( - r = rand.New(rand.NewSource(time.Now().UnixNano())) - mu sync.Mutex -) - -// Int implements rand.Int on the grpcrand global source. -func Int() int { - mu.Lock() - defer mu.Unlock() - return r.Int() -} - -// Int63n implements rand.Int63n on the grpcrand global source. -func Int63n(n int64) int64 { - mu.Lock() - defer mu.Unlock() - return r.Int63n(n) -} - -// Intn implements rand.Intn on the grpcrand global source. -func Intn(n int) int { - mu.Lock() - defer mu.Unlock() - return r.Intn(n) -} - -// Int31n implements rand.Int31n on the grpcrand global source. -func Int31n(n int32) int32 { - mu.Lock() - defer mu.Unlock() - return r.Int31n(n) -} - -// Float64 implements rand.Float64 on the grpcrand global source. -func Float64() float64 { - mu.Lock() - defer mu.Unlock() - return r.Float64() -} - -// Uint64 implements rand.Uint64 on the grpcrand global source. -func Uint64() uint64 { - mu.Lock() - defer mu.Unlock() - return r.Uint64() -} - -// Uint32 implements rand.Uint32 on the grpcrand global source. -func Uint32() uint32 { - mu.Lock() - defer mu.Unlock() - return r.Uint32() -} - -// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source. -func ExpFloat64() float64 { - mu.Lock() - defer mu.Unlock() - return r.ExpFloat64() -} - -// Shuffle implements rand.Shuffle on the grpcrand global source. -var Shuffle = func(n int, f func(int, int)) { - mu.Lock() - defer mu.Unlock() - r.Shuffle(n, f) -} diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go deleted file mode 100644 index c37299af..00000000 --- a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go +++ /dev/null @@ -1,73 +0,0 @@ -//go:build go1.21 - -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed 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 grpcrand implements math/rand functions in a concurrent-safe way -// with a global random source, independent of math/rand's global source. -package grpcrand - -import "math/rand" - -// This implementation will be used for Go version 1.21 or newer. -// For older versions, the original implementation with mutex will be used. - -// Int implements rand.Int on the grpcrand global source. -func Int() int { - return rand.Int() -} - -// Int63n implements rand.Int63n on the grpcrand global source. -func Int63n(n int64) int64 { - return rand.Int63n(n) -} - -// Intn implements rand.Intn on the grpcrand global source. -func Intn(n int) int { - return rand.Intn(n) -} - -// Int31n implements rand.Int31n on the grpcrand global source. -func Int31n(n int32) int32 { - return rand.Int31n(n) -} - -// Float64 implements rand.Float64 on the grpcrand global source. -func Float64() float64 { - return rand.Float64() -} - -// Uint64 implements rand.Uint64 on the grpcrand global source. -func Uint64() uint64 { - return rand.Uint64() -} - -// Uint32 implements rand.Uint32 on the grpcrand global source. -func Uint32() uint32 { - return rand.Uint32() -} - -// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source. -func ExpFloat64() float64 { - return rand.ExpFloat64() -} - -// Shuffle implements rand.Shuffle on the grpcrand global source. -var Shuffle = func(n int, f func(int, int)) { - rand.Shuffle(n, f) -} diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go b/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go index 9f409096..e8d86698 100644 --- a/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go @@ -20,8 +20,6 @@ package grpcutil import ( "strings" - - "google.golang.org/grpc/internal/envconfig" ) // RegisteredCompressorNames holds names of the registered compressors. @@ -40,8 +38,5 @@ func IsCompressorNameRegistered(name string) bool { // RegisteredCompressors returns a string of registered compressor names // separated by comma. func RegisteredCompressors() string { - if !envconfig.AdvertiseCompressors { - return "" - } return strings.Join(RegisteredCompressorNames, ",") } diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index 48d24bdb..5d665398 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -106,6 +106,14 @@ var ( // This is used in the 1.0 release of gcp/observability, and thus must not be // deleted or changed. ClearGlobalDialOptions func() + + // AddGlobalPerTargetDialOptions adds a PerTargetDialOption that will be + // configured for newly created ClientConns. + AddGlobalPerTargetDialOptions any // func (opt any) + // ClearGlobalPerTargetDialOptions clears the slice of global late apply + // dial options. + ClearGlobalPerTargetDialOptions func() + // JoinDialOptions combines the dial options passed as arguments into a // single dial option. JoinDialOptions any // func(...grpc.DialOption) grpc.DialOption @@ -126,7 +134,8 @@ var ( // deleted or changed. BinaryLogger any // func(binarylog.Logger) grpc.ServerOption - // SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a provided grpc.ClientConn + // SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a + // provided grpc.ClientConn. SubscribeToConnectivityStateChanges any // func(*grpc.ClientConn, grpcsync.Subscriber) // NewXDSResolverWithConfigForTesting creates a new xds resolver builder using @@ -184,25 +193,25 @@ var ( ChannelzTurnOffForTesting func() - // TriggerXDSResourceNameNotFoundForTesting triggers the resource-not-found - // error for a given resource type and name. This is usually triggered when - // the associated watch timer fires. For testing purposes, having this - // function makes events more predictable than relying on timer events. - TriggerXDSResourceNameNotFoundForTesting any // func(func(xdsresource.Type, string), string, string) error + // TriggerXDSResourceNotFoundForTesting causes the provided xDS Client to + // invoke resource-not-found error for the given resource type and name. + TriggerXDSResourceNotFoundForTesting any // func(xdsclient.XDSClient, xdsresource.Type, string) error - // TriggerXDSResourceNameNotFoundClient invokes the testing xDS Client - // singleton to invoke resource not found for a resource type name and - // resource name. - TriggerXDSResourceNameNotFoundClient any // func(string, string) error - - // FromOutgoingContextRaw returns the un-merged, intermediary contents of metadata.rawMD. + // FromOutgoingContextRaw returns the un-merged, intermediary contents of + // metadata.rawMD. FromOutgoingContextRaw any // func(context.Context) (metadata.MD, [][]string, bool) - // UserSetDefaultScheme is set to true if the user has overridden the default resolver scheme. + // UserSetDefaultScheme is set to true if the user has overridden the + // default resolver scheme. UserSetDefaultScheme bool = false + + // ShuffleAddressListForTesting pseudo-randomizes the order of addresses. n + // is the number of elements. swap swaps the elements with indexes i and j. + ShuffleAddressListForTesting any // func(n int, swap func(i, j int)) ) -// HealthChecker defines the signature of the client-side LB channel health checking function. +// HealthChecker defines the signature of the client-side LB channel health +// checking function. // // The implementation is expected to create a health checking RPC stream by // calling newStream(), watch for the health status of serviceName, and report diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index abab35e2..4552db16 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -24,6 +24,7 @@ import ( "context" "encoding/json" "fmt" + "math/rand" "net" "os" "strconv" @@ -35,28 +36,35 @@ import ( "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/envconfig" - "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/internal/resolver/dns/internal" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" ) -// EnableSRVLookups controls whether the DNS resolver attempts to fetch gRPCLB -// addresses from SRV records. Must not be changed after init time. -var EnableSRVLookups = false +var ( + // EnableSRVLookups controls whether the DNS resolver attempts to fetch gRPCLB + // addresses from SRV records. Must not be changed after init time. + EnableSRVLookups = false -// ResolvingTimeout specifies the maximum duration for a DNS resolution request. -// If the timeout expires before a response is received, the request will be canceled. -// -// It is recommended to set this value at application startup. Avoid modifying this variable -// after initialization as it's not thread-safe for concurrent modification. -var ResolvingTimeout = 30 * time.Second + // MinResolutionInterval is the minimum interval at which re-resolutions are + // allowed. This helps to prevent excessive re-resolution. + MinResolutionInterval = 30 * time.Second -var logger = grpclog.Component("dns") + // ResolvingTimeout specifies the maximum duration for a DNS resolution request. + // If the timeout expires before a response is received, the request will be canceled. + // + // It is recommended to set this value at application startup. Avoid modifying this variable + // after initialization as it's not thread-safe for concurrent modification. + ResolvingTimeout = 30 * time.Second + + logger = grpclog.Component("dns") +) func init() { resolver.Register(NewBuilder()) internal.TimeAfterFunc = time.After + internal.TimeNowFunc = time.Now + internal.TimeUntilFunc = time.Until internal.NewNetResolver = newNetResolver internal.AddressDialer = addressDialer } @@ -203,12 +211,12 @@ func (d *dnsResolver) watcher() { err = d.cc.UpdateState(*state) } - var waitTime time.Duration + var nextResolutionTime time.Time if err == nil { // Success resolving, wait for the next ResolveNow. However, also wait 30 // seconds at the very least to prevent constantly re-resolving. backoffIndex = 1 - waitTime = internal.MinResolutionRate + nextResolutionTime = internal.TimeNowFunc().Add(MinResolutionInterval) select { case <-d.ctx.Done(): return @@ -217,13 +225,13 @@ func (d *dnsResolver) watcher() { } else { // Poll on an error found in DNS Resolver or an error received from // ClientConn. - waitTime = backoff.DefaultExponential.Backoff(backoffIndex) + nextResolutionTime = internal.TimeNowFunc().Add(backoff.DefaultExponential.Backoff(backoffIndex)) backoffIndex++ } select { case <-d.ctx.Done(): return - case <-internal.TimeAfterFunc(waitTime): + case <-internal.TimeAfterFunc(internal.TimeUntilFunc(nextResolutionTime)): } } } @@ -417,7 +425,7 @@ func chosenByPercentage(a *int) bool { if a == nil { return true } - return grpcrand.Intn(100)+1 <= *a + return rand.Intn(100)+1 <= *a } func canaryingSC(js string) string { diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go b/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go index c7fc557d..c0eae4f5 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go @@ -28,7 +28,7 @@ import ( // NetResolver groups the methods on net.Resolver that are used by the DNS // resolver implementation. This allows the default net.Resolver instance to be -// overidden from tests. +// overridden from tests. type NetResolver interface { LookupHost(ctx context.Context, host string) (addrs []string, err error) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error) @@ -50,16 +50,23 @@ var ( // The following vars are overridden from tests. var ( - // MinResolutionRate is the minimum rate at which re-resolutions are - // allowed. This helps to prevent excessive re-resolution. - MinResolutionRate = 30 * time.Second - // TimeAfterFunc is used by the DNS resolver to wait for the given duration - // to elapse. In non-test code, this is implemented by time.After. In test + // to elapse. In non-test code, this is implemented by time.After. In test // code, this can be used to control the amount of time the resolver is // blocked waiting for the duration to elapse. TimeAfterFunc func(time.Duration) <-chan time.Time + // TimeNowFunc is used by the DNS resolver to get the current time. + // In non-test code, this is implemented by time.Now. In test code, + // this can be used to control the current time for the resolver. + TimeNowFunc func() time.Time + + // TimeUntilFunc is used by the DNS resolver to calculate the remaining + // wait time for re-resolution. In non-test code, this is implemented by + // time.Until. In test code, this can be used to control the remaining + // time for resolver to wait for re-resolution. + TimeUntilFunc func(time.Time) time.Duration + // NewNetResolver returns the net.Resolver instance for the given target. NewNetResolver func(string) (NetResolver, error) diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index 83c38298..3deadfb4 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -193,7 +193,7 @@ type goAway struct { code http2.ErrCode debugData []byte headsUp bool - closeConn error // if set, loopyWriter will exit, resulting in conn closure + closeConn error // if set, loopyWriter will exit with this error } func (*goAway) isTransportResponseFrame() bool { return false } @@ -336,7 +336,7 @@ func (c *controlBuffer) put(it cbItem) error { return err } -func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, error) { +func (c *controlBuffer) executeAndPut(f func() bool, it cbItem) (bool, error) { var wakeUp bool c.mu.Lock() if c.err != nil { @@ -344,7 +344,7 @@ func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, err return false, c.err } if f != nil { - if !f(it) { // f wasn't successful + if !f() { // f wasn't successful c.mu.Unlock() return false, nil } @@ -495,21 +495,22 @@ type loopyWriter struct { ssGoAwayHandler func(*goAway) (bool, error) } -func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger) *loopyWriter { +func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger, goAwayHandler func(*goAway) (bool, error)) *loopyWriter { var buf bytes.Buffer l := &loopyWriter{ - side: s, - cbuf: cbuf, - sendQuota: defaultWindowSize, - oiws: defaultWindowSize, - estdStreams: make(map[uint32]*outStream), - activeStreams: newOutStreamList(), - framer: fr, - hBuf: &buf, - hEnc: hpack.NewEncoder(&buf), - bdpEst: bdpEst, - conn: conn, - logger: logger, + side: s, + cbuf: cbuf, + sendQuota: defaultWindowSize, + oiws: defaultWindowSize, + estdStreams: make(map[uint32]*outStream), + activeStreams: newOutStreamList(), + framer: fr, + hBuf: &buf, + hEnc: hpack.NewEncoder(&buf), + bdpEst: bdpEst, + conn: conn, + logger: logger, + ssGoAwayHandler: goAwayHandler, } return l } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index deba0c4d..3c63c706 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -114,11 +114,11 @@ type http2Client struct { streamQuota int64 streamsQuotaAvailable chan struct{} waitingStreams uint32 - nextID uint32 registeredCompressors string // Do not access controlBuf with mu held. mu sync.Mutex // guard the following variables + nextID uint32 state transportState activeStreams map[uint32]*Stream // prevGoAway ID records the Last-Stream-ID in the previous GOAway frame. @@ -408,10 +408,10 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts readerErrCh := make(chan error, 1) go t.reader(readerErrCh) defer func() { - if err == nil { - err = <-readerErrCh - } if err != nil { + // writerDone should be closed since the loopy goroutine + // wouldn't have started in the case this function returns an error. + close(t.writerDone) t.Close(err) } }() @@ -458,8 +458,12 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts if err := t.framer.writer.Flush(); err != nil { return nil, err } + // Block until the server preface is received successfully or an error occurs. + if err = <-readerErrCh; err != nil { + return nil, err + } go func() { - t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) + t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler) if err := t.loopy.run(); !isIOError(err) { // Immediately close the connection, as the loopy writer returns // when there are no more active streams and we were draining (the @@ -517,6 +521,17 @@ func (t *http2Client) getPeer() *peer.Peer { } } +// OutgoingGoAwayHandler writes a GOAWAY to the connection. Always returns (false, err) as we want the GoAway +// to be the last frame loopy writes to the transport. +func (t *http2Client) outgoingGoAwayHandler(g *goAway) (bool, error) { + t.mu.Lock() + defer t.mu.Unlock() + if err := t.framer.fr.WriteGoAway(t.nextID-2, http2.ErrCodeNo, g.debugData); err != nil { + return false, err + } + return false, g.closeConn +} + func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) ([]hpack.HeaderField, error) { aud := t.createAudience(callHdr) ri := credentials.RequestInfo{ @@ -781,7 +796,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, firstTry := true var ch chan struct{} transportDrainRequired := false - checkForStreamQuota := func(it any) bool { + checkForStreamQuota := func() bool { if t.streamQuota <= 0 { // Can go negative if server decreases it. if firstTry { t.waitingStreams++ @@ -793,23 +808,24 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, t.waitingStreams-- } t.streamQuota-- - h := it.(*headerFrame) - h.streamID = t.nextID - t.nextID += 2 - - // Drain client transport if nextID > MaxStreamID which signals gRPC that - // the connection is closed and a new one must be created for subsequent RPCs. - transportDrainRequired = t.nextID > MaxStreamID - s.id = h.streamID - s.fc = &inFlow{limit: uint32(t.initialWindowSize)} t.mu.Lock() if t.state == draining || t.activeStreams == nil { // Can be niled from Close(). t.mu.Unlock() return false // Don't create a stream if the transport is already closed. } + + hdr.streamID = t.nextID + t.nextID += 2 + // Drain client transport if nextID > MaxStreamID which signals gRPC that + // the connection is closed and a new one must be created for subsequent RPCs. + transportDrainRequired = t.nextID > MaxStreamID + + s.id = hdr.streamID + s.fc = &inFlow{limit: uint32(t.initialWindowSize)} t.activeStreams[s.id] = s t.mu.Unlock() + if t.streamQuota > 0 && t.waitingStreams > 0 { select { case t.streamsQuotaAvailable <- struct{}{}: @@ -819,13 +835,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } var hdrListSizeErr error - checkForHeaderListSize := func(it any) bool { + checkForHeaderListSize := func() bool { if t.maxSendHeaderListSize == nil { return true } - hdrFrame := it.(*headerFrame) var sz int64 - for _, f := range hdrFrame.hf { + for _, f := range hdr.hf { if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) { hdrListSizeErr = status.Errorf(codes.Internal, "header list size to send violates the maximum size (%d bytes) set by server", *t.maxSendHeaderListSize) return false @@ -834,8 +849,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } for { - success, err := t.controlBuf.executeAndPut(func(it any) bool { - return checkForHeaderListSize(it) && checkForStreamQuota(it) + success, err := t.controlBuf.executeAndPut(func() bool { + return checkForHeaderListSize() && checkForStreamQuota() }, hdr) if err != nil { // Connection closed. @@ -946,7 +961,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. rst: rst, rstCode: rstCode, } - addBackStreamQuota := func(any) bool { + addBackStreamQuota := func() bool { t.streamQuota++ if t.streamQuota > 0 && t.waitingStreams > 0 { select { @@ -966,7 +981,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. // Close kicks off the shutdown process of the transport. This should be called // only once on a transport. Once it is called, the transport should not be -// accessed any more. +// accessed anymore. func (t *http2Client) Close(err error) { t.mu.Lock() // Make sure we only close once. @@ -991,7 +1006,10 @@ func (t *http2Client) Close(err error) { t.kpDormancyCond.Signal() } t.mu.Unlock() - t.controlBuf.finish() + // Per HTTP/2 spec, a GOAWAY frame must be sent before closing the + // connection. See https://httpwg.org/specs/rfc7540.html#GOAWAY. + t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte("client transport shutdown"), closeConn: err}) + <-t.writerDone t.cancel() t.conn.Close() channelz.RemoveEntry(t.channelz.ID) @@ -1099,7 +1117,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { // for the transport and the stream based on the current bdp // estimation. func (t *http2Client) updateFlowControl(n uint32) { - updateIWS := func(any) bool { + updateIWS := func() bool { t.initialWindowSize = int32(n) t.mu.Lock() for _, s := range t.activeStreams { @@ -1252,7 +1270,7 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) { } updateFuncs = append(updateFuncs, updateStreamQuota) } - t.controlBuf.executeAndPut(func(any) bool { + t.controlBuf.executeAndPut(func() bool { for _, f := range updateFuncs { f() } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index d582e047..b7091165 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -25,6 +25,7 @@ import ( "fmt" "io" "math" + "math/rand" "net" "net/http" "strconv" @@ -43,7 +44,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" - "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" @@ -330,8 +330,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, t.handleSettings(sf) go func() { - t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) - t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler + t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler) err := t.loopy.run() close(t.loopyWriterDone) if !isIOError(err) { @@ -860,7 +859,7 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } return nil }) - t.controlBuf.executeAndPut(func(any) bool { + t.controlBuf.executeAndPut(func() bool { for _, f := range updateFuncs { f() } @@ -1014,12 +1013,13 @@ func (t *http2Server) writeHeaderLocked(s *Stream) error { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) } headerFields = appendHeaderFieldsFromMD(headerFields, s.header) - success, err := t.controlBuf.executeAndPut(t.checkForHeaderListSize, &headerFrame{ + hf := &headerFrame{ streamID: s.id, hf: headerFields, endStream: false, onWrite: t.setResetPingStrikes, - }) + } + success, err := t.controlBuf.executeAndPut(func() bool { return t.checkForHeaderListSize(hf) }, hf) if !success { if err != nil { return err @@ -1208,7 +1208,7 @@ func (t *http2Server) keepalive() { continue } if outstandingPing && kpTimeoutLeft <= 0 { - t.Close(fmt.Errorf("keepalive ping not acked within timeout %s", t.kp.Time)) + t.Close(fmt.Errorf("keepalive ping not acked within timeout %s", t.kp.Timeout)) return } if !outstandingPing { @@ -1440,7 +1440,7 @@ func getJitter(v time.Duration) time.Duration { } // Generate a jitter between +/- 10% of the value. r := int64(v / 10) - j := grpcrand.Int63n(2*r) - r + j := rand.Int63n(2*r) - r return time.Duration(j) } diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 0d2a6e47..4b39c0ad 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -304,7 +304,7 @@ func (s *Stream) isHeaderSent() bool { } // updateHeaderSent updates headerSent and returns true -// if it was alreay set. It is valid only on server-side. +// if it was already set. It is valid only on server-side. func (s *Stream) updateHeaderSent() bool { return atomic.SwapUint32(&s.headerSent, 1) == 1 } diff --git a/vendor/google.golang.org/grpc/peer/peer.go b/vendor/google.golang.org/grpc/peer/peer.go index a821ff9b..499a49c8 100644 --- a/vendor/google.golang.org/grpc/peer/peer.go +++ b/vendor/google.golang.org/grpc/peer/peer.go @@ -22,7 +22,9 @@ package peer import ( "context" + "fmt" "net" + "strings" "google.golang.org/grpc/credentials" ) @@ -39,6 +41,34 @@ type Peer struct { AuthInfo credentials.AuthInfo } +// String ensures the Peer types implements the Stringer interface in order to +// allow to print a context with a peerKey value effectively. +func (p *Peer) String() string { + if p == nil { + return "Peer<nil>" + } + sb := &strings.Builder{} + sb.WriteString("Peer{") + if p.Addr != nil { + fmt.Fprintf(sb, "Addr: '%s', ", p.Addr.String()) + } else { + fmt.Fprintf(sb, "Addr: <nil>, ") + } + if p.LocalAddr != nil { + fmt.Fprintf(sb, "LocalAddr: '%s', ", p.LocalAddr.String()) + } else { + fmt.Fprintf(sb, "LocalAddr: <nil>, ") + } + if p.AuthInfo != nil { + fmt.Fprintf(sb, "AuthInfo: '%s'", p.AuthInfo.AuthType()) + } else { + fmt.Fprintf(sb, "AuthInfo: <nil>") + } + sb.WriteString("}") + + return sb.String() +} + type peerKey struct{} // NewContext creates a new context with peer information attached. diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index bf56faa7..bdaa2130 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -20,8 +20,9 @@ package grpc import ( "context" + "fmt" "io" - "sync" + "sync/atomic" "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" @@ -32,35 +33,43 @@ import ( "google.golang.org/grpc/status" ) +// pickerGeneration stores a picker and a channel used to signal that a picker +// newer than this one is available. +type pickerGeneration struct { + // picker is the picker produced by the LB policy. May be nil if a picker + // has never been produced. + picker balancer.Picker + // blockingCh is closed when the picker has been invalidated because there + // is a new one available. + blockingCh chan struct{} +} + // pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick // actions and unblock when there's a picker update. type pickerWrapper struct { - mu sync.Mutex - done bool - blockingCh chan struct{} - picker balancer.Picker + // If pickerGen holds a nil pointer, the pickerWrapper is closed. + pickerGen atomic.Pointer[pickerGeneration] statsHandlers []stats.Handler // to record blocking picker calls } func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper { - return &pickerWrapper{ - blockingCh: make(chan struct{}), + pw := &pickerWrapper{ statsHandlers: statsHandlers, } + pw.pickerGen.Store(&pickerGeneration{ + blockingCh: make(chan struct{}), + }) + return pw } -// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. +// updatePicker is called by UpdateState calls from the LB policy. It +// unblocks all blocked pick. func (pw *pickerWrapper) updatePicker(p balancer.Picker) { - pw.mu.Lock() - if pw.done { - pw.mu.Unlock() - return - } - pw.picker = p - // pw.blockingCh should never be nil. - close(pw.blockingCh) - pw.blockingCh = make(chan struct{}) - pw.mu.Unlock() + old := pw.pickerGen.Swap(&pickerGeneration{ + picker: p, + blockingCh: make(chan struct{}), + }) + close(old.blockingCh) } // doneChannelzWrapper performs the following: @@ -97,27 +106,24 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. var lastPickErr error for { - pw.mu.Lock() - if pw.done { - pw.mu.Unlock() + pg := pw.pickerGen.Load() + if pg == nil { return nil, balancer.PickResult{}, ErrClientConnClosing } - - if pw.picker == nil { - ch = pw.blockingCh + if pg.picker == nil { + ch = pg.blockingCh } - if ch == pw.blockingCh { + if ch == pg.blockingCh { // This could happen when either: // - pw.picker is nil (the previous if condition), or - // - has called pick on the current picker. - pw.mu.Unlock() + // - we have already called pick on the current picker. select { case <-ctx.Done(): var errStr string if lastPickErr != nil { errStr = "latest balancer error: " + lastPickErr.Error() } else { - errStr = ctx.Err().Error() + errStr = fmt.Sprintf("received context error while waiting for new LB policy update: %s", ctx.Err().Error()) } switch ctx.Err() { case context.DeadlineExceeded: @@ -144,9 +150,8 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. } } - ch = pw.blockingCh - p := pw.picker - pw.mu.Unlock() + ch = pg.blockingCh + p := pg.picker pickResult, err := p.Pick(info) if err != nil { @@ -196,24 +201,15 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. } func (pw *pickerWrapper) close() { - pw.mu.Lock() - defer pw.mu.Unlock() - if pw.done { - return - } - pw.done = true - close(pw.blockingCh) + old := pw.pickerGen.Swap(nil) + close(old.blockingCh) } // reset clears the pickerWrapper and prepares it for being used again when idle // mode is exited. func (pw *pickerWrapper) reset() { - pw.mu.Lock() - defer pw.mu.Unlock() - if pw.done { - return - } - pw.blockingCh = make(chan struct{}) + old := pw.pickerGen.Swap(&pickerGeneration{blockingCh: make(chan struct{})}) + close(old.blockingCh) } // dropError is a wrapper error that indicates the LB policy wishes to drop the diff --git a/vendor/google.golang.org/grpc/reflection/adapt.go b/vendor/google.golang.org/grpc/reflection/adapt.go index 33b907a3..6997e474 100644 --- a/vendor/google.golang.org/grpc/reflection/adapt.go +++ b/vendor/google.golang.org/grpc/reflection/adapt.go @@ -19,10 +19,11 @@ package reflection import ( + "google.golang.org/grpc/reflection/internal" + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" - v1alphareflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" ) // asV1Alpha returns an implementation of the v1alpha version of the reflection @@ -44,7 +45,7 @@ type v1AlphaServerStreamAdapter struct { } func (s v1AlphaServerStreamAdapter) Send(response *v1reflectionpb.ServerReflectionResponse) error { - return s.ServerReflection_ServerReflectionInfoServer.Send(v1ToV1AlphaResponse(response)) + return s.ServerReflection_ServerReflectionInfoServer.Send(internal.V1ToV1AlphaResponse(response)) } func (s v1AlphaServerStreamAdapter) Recv() (*v1reflectionpb.ServerReflectionRequest, error) { @@ -52,136 +53,5 @@ func (s v1AlphaServerStreamAdapter) Recv() (*v1reflectionpb.ServerReflectionRequ if err != nil { return nil, err } - return v1AlphaToV1Request(resp), nil -} - -func v1ToV1AlphaResponse(v1 *v1reflectionpb.ServerReflectionResponse) *v1alphareflectionpb.ServerReflectionResponse { - var v1alpha v1alphareflectionpb.ServerReflectionResponse - v1alpha.ValidHost = v1.ValidHost - if v1.OriginalRequest != nil { - v1alpha.OriginalRequest = v1ToV1AlphaRequest(v1.OriginalRequest) - } - switch mr := v1.MessageResponse.(type) { - case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: - if mr != nil { - v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1alphareflectionpb.FileDescriptorResponse{ - FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), - }, - } - } - case *v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: - if mr != nil { - v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ - AllExtensionNumbersResponse: &v1alphareflectionpb.ExtensionNumberResponse{ - BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), - ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), - }, - } - } - case *v1reflectionpb.ServerReflectionResponse_ListServicesResponse: - if mr != nil { - svcs := make([]*v1alphareflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) - for i, svc := range mr.ListServicesResponse.GetService() { - svcs[i] = &v1alphareflectionpb.ServiceResponse{ - Name: svc.GetName(), - } - } - v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse{ - ListServicesResponse: &v1alphareflectionpb.ListServiceResponse{ - Service: svcs, - }, - } - } - case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: - if mr != nil { - v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1alphareflectionpb.ErrorResponse{ - ErrorCode: mr.ErrorResponse.GetErrorCode(), - ErrorMessage: mr.ErrorResponse.GetErrorMessage(), - }, - } - } - default: - // no value set - } - return &v1alpha -} - -func v1AlphaToV1Request(v1alpha *v1alphareflectionpb.ServerReflectionRequest) *v1reflectionpb.ServerReflectionRequest { - var v1 v1reflectionpb.ServerReflectionRequest - v1.Host = v1alpha.Host - switch mr := v1alpha.MessageRequest.(type) { - case *v1alphareflectionpb.ServerReflectionRequest_FileByFilename: - v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileByFilename{ - FileByFilename: mr.FileByFilename, - } - case *v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol: - v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingSymbol{ - FileContainingSymbol: mr.FileContainingSymbol, - } - case *v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension: - if mr.FileContainingExtension != nil { - v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingExtension{ - FileContainingExtension: &v1reflectionpb.ExtensionRequest{ - ContainingType: mr.FileContainingExtension.GetContainingType(), - ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), - }, - } - } - case *v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: - v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ - AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, - } - case *v1alphareflectionpb.ServerReflectionRequest_ListServices: - v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_ListServices{ - ListServices: mr.ListServices, - } - default: - // no value set - } - return &v1 -} - -func v1ToV1AlphaRequest(v1 *v1reflectionpb.ServerReflectionRequest) *v1alphareflectionpb.ServerReflectionRequest { - var v1alpha v1alphareflectionpb.ServerReflectionRequest - v1alpha.Host = v1.Host - switch mr := v1.MessageRequest.(type) { - case *v1reflectionpb.ServerReflectionRequest_FileByFilename: - if mr != nil { - v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileByFilename{ - FileByFilename: mr.FileByFilename, - } - } - case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: - if mr != nil { - v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol{ - FileContainingSymbol: mr.FileContainingSymbol, - } - } - case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: - if mr != nil { - v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension{ - FileContainingExtension: &v1alphareflectionpb.ExtensionRequest{ - ContainingType: mr.FileContainingExtension.GetContainingType(), - ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), - }, - } - } - case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: - if mr != nil { - v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ - AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, - } - } - case *v1reflectionpb.ServerReflectionRequest_ListServices: - if mr != nil { - v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_ListServices{ - ListServices: mr.ListServices, - } - } - default: - // no value set - } - return &v1alpha + return internal.V1AlphaToV1Request(resp), nil } diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go index 8953c9d8..666eda8e 100644 --- a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go @@ -21,7 +21,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v4.25.2 // source: grpc/reflection/v1/reflection.proto diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go index d6cdd5b5..17d21fde 100644 --- a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go @@ -21,7 +21,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 +// - protoc-gen-go-grpc v1.4.0 // - protoc v4.25.2 // source: grpc/reflection/v1/reflection.proto @@ -36,8 +36,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( ServerReflection_ServerReflectionInfo_FullMethodName = "/grpc.reflection.v1.ServerReflection/ServerReflectionInfo" @@ -61,11 +61,12 @@ func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClie } func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) { - stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &serverReflectionServerReflectionInfoClient{stream} + x := &serverReflectionServerReflectionInfoClient{ClientStream: stream} return x, nil } @@ -120,7 +121,7 @@ func RegisterServerReflectionServer(s grpc.ServiceRegistrar, srv ServerReflectio } func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream}) + return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{ServerStream: stream}) } type ServerReflection_ServerReflectionInfoServer interface { diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go index 929733e7..cd032ace 100644 --- a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v4.25.2 // grpc/reflection/v1alpha/reflection.proto is a deprecated file. diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go index ef691406..93886e38 100644 --- a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 +// - protoc-gen-go-grpc v1.4.0 // - protoc v4.25.2 // grpc/reflection/v1alpha/reflection.proto is a deprecated file. @@ -33,8 +33,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( ServerReflection_ServerReflectionInfo_FullMethodName = "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo" @@ -58,11 +58,12 @@ func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClie } func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) { - stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &serverReflectionServerReflectionInfoClient{stream} + x := &serverReflectionServerReflectionInfoClient{ClientStream: stream} return x, nil } @@ -117,7 +118,7 @@ func RegisterServerReflectionServer(s grpc.ServiceRegistrar, srv ServerReflectio } func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream}) + return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{ServerStream: stream}) } type ServerReflection_ServerReflectionInfoServer interface { diff --git a/vendor/google.golang.org/grpc/reflection/internal/internal.go b/vendor/google.golang.org/grpc/reflection/internal/internal.go new file mode 100644 index 00000000..36ee6507 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/internal/internal.go @@ -0,0 +1,436 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed 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 internal contains code that is shared by both reflection package and +// the test package. The packages are split in this way inorder to avoid +// depenedency to deprecated package github.com/golang/protobuf. +package internal + +import ( + "io" + "sort" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" + v1alphareflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + +// ServiceInfoProvider is an interface used to retrieve metadata about the +// services to expose. +type ServiceInfoProvider interface { + GetServiceInfo() map[string]grpc.ServiceInfo +} + +// ExtensionResolver is the interface used to query details about extensions. +// This interface is satisfied by protoregistry.GlobalTypes. +type ExtensionResolver interface { + protoregistry.ExtensionTypeResolver + RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) +} + +// ServerReflectionServer is the server API for ServerReflection service. +type ServerReflectionServer struct { + v1alphareflectiongrpc.UnimplementedServerReflectionServer + S ServiceInfoProvider + DescResolver protodesc.Resolver + ExtResolver ExtensionResolver +} + +// FileDescWithDependencies returns a slice of serialized fileDescriptors in +// wire format ([]byte). The fileDescriptors will include fd and all the +// transitive dependencies of fd with names not in sentFileDescriptors. +func (s *ServerReflectionServer) FileDescWithDependencies(fd protoreflect.FileDescriptor, sentFileDescriptors map[string]bool) ([][]byte, error) { + if fd.IsPlaceholder() { + // If the given root file is a placeholder, treat it + // as missing instead of serializing it. + return nil, protoregistry.NotFound + } + var r [][]byte + queue := []protoreflect.FileDescriptor{fd} + for len(queue) > 0 { + currentfd := queue[0] + queue = queue[1:] + if currentfd.IsPlaceholder() { + // Skip any missing files in the dependency graph. + continue + } + if sent := sentFileDescriptors[currentfd.Path()]; len(r) == 0 || !sent { + sentFileDescriptors[currentfd.Path()] = true + fdProto := protodesc.ToFileDescriptorProto(currentfd) + currentfdEncoded, err := proto.Marshal(fdProto) + if err != nil { + return nil, err + } + r = append(r, currentfdEncoded) + } + for i := 0; i < currentfd.Imports().Len(); i++ { + queue = append(queue, currentfd.Imports().Get(i)) + } + } + return r, nil +} + +// FileDescEncodingContainingSymbol finds the file descriptor containing the +// given symbol, finds all of its previously unsent transitive dependencies, +// does marshalling on them, and returns the marshalled result. The given symbol +// can be a type, a service or a method. +func (s *ServerReflectionServer) FileDescEncodingContainingSymbol(name string, sentFileDescriptors map[string]bool) ([][]byte, error) { + d, err := s.DescResolver.FindDescriptorByName(protoreflect.FullName(name)) + if err != nil { + return nil, err + } + return s.FileDescWithDependencies(d.ParentFile(), sentFileDescriptors) +} + +// FileDescEncodingContainingExtension finds the file descriptor containing +// given extension, finds all of its previously unsent transitive dependencies, +// does marshalling on them, and returns the marshalled result. +func (s *ServerReflectionServer) FileDescEncodingContainingExtension(typeName string, extNum int32, sentFileDescriptors map[string]bool) ([][]byte, error) { + xt, err := s.ExtResolver.FindExtensionByNumber(protoreflect.FullName(typeName), protoreflect.FieldNumber(extNum)) + if err != nil { + return nil, err + } + return s.FileDescWithDependencies(xt.TypeDescriptor().ParentFile(), sentFileDescriptors) +} + +// AllExtensionNumbersForTypeName returns all extension numbers for the given type. +func (s *ServerReflectionServer) AllExtensionNumbersForTypeName(name string) ([]int32, error) { + var numbers []int32 + s.ExtResolver.RangeExtensionsByMessage(protoreflect.FullName(name), func(xt protoreflect.ExtensionType) bool { + numbers = append(numbers, int32(xt.TypeDescriptor().Number())) + return true + }) + sort.Slice(numbers, func(i, j int) bool { + return numbers[i] < numbers[j] + }) + if len(numbers) == 0 { + // maybe return an error if given type name is not known + if _, err := s.DescResolver.FindDescriptorByName(protoreflect.FullName(name)); err != nil { + return nil, err + } + } + return numbers, nil +} + +// ListServices returns the names of services this server exposes. +func (s *ServerReflectionServer) ListServices() []*v1reflectionpb.ServiceResponse { + serviceInfo := s.S.GetServiceInfo() + resp := make([]*v1reflectionpb.ServiceResponse, 0, len(serviceInfo)) + for svc := range serviceInfo { + resp = append(resp, &v1reflectionpb.ServiceResponse{Name: svc}) + } + sort.Slice(resp, func(i, j int) bool { + return resp[i].Name < resp[j].Name + }) + return resp +} + +// ServerReflectionInfo is the reflection service handler. +func (s *ServerReflectionServer) ServerReflectionInfo(stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoServer) error { + sentFileDescriptors := make(map[string]bool) + for { + in, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + + out := &v1reflectionpb.ServerReflectionResponse{ + ValidHost: in.Host, + OriginalRequest: in, + } + switch req := in.MessageRequest.(type) { + case *v1reflectionpb.ServerReflectionRequest_FileByFilename: + var b [][]byte + fd, err := s.DescResolver.FindFileByPath(req.FileByFilename) + if err == nil { + b, err = s.FileDescWithDependencies(fd, sentFileDescriptors) + } + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: + b, err := s.FileDescEncodingContainingSymbol(req.FileContainingSymbol, sentFileDescriptors) + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: + typeName := req.FileContainingExtension.ContainingType + extNum := req.FileContainingExtension.ExtensionNumber + b, err := s.FileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors) + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, + } + } + case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + extNums, err := s.AllExtensionNumbersForTypeName(req.AllExtensionNumbersOfType) + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ + BaseTypeName: req.AllExtensionNumbersOfType, + ExtensionNumber: extNums, + }, + } + } + case *v1reflectionpb.ServerReflectionRequest_ListServices: + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1reflectionpb.ListServiceResponse{ + Service: s.ListServices(), + }, + } + default: + return status.Errorf(codes.InvalidArgument, "invalid MessageRequest: %v", in.MessageRequest) + } + + if err := stream.Send(out); err != nil { + return err + } + } +} + +// V1ToV1AlphaResponse converts a v1 ServerReflectionResponse to a v1alpha. +func V1ToV1AlphaResponse(v1 *v1reflectionpb.ServerReflectionResponse) *v1alphareflectionpb.ServerReflectionResponse { + var v1alpha v1alphareflectionpb.ServerReflectionResponse + v1alpha.ValidHost = v1.ValidHost + if v1.OriginalRequest != nil { + v1alpha.OriginalRequest = V1ToV1AlphaRequest(v1.OriginalRequest) + } + switch mr := v1.MessageResponse.(type) { + case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1alphareflectionpb.FileDescriptorResponse{ + FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1alphareflectionpb.ExtensionNumberResponse{ + BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), + ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_ListServicesResponse: + if mr != nil { + svcs := make([]*v1alphareflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) + for i, svc := range mr.ListServicesResponse.GetService() { + svcs[i] = &v1alphareflectionpb.ServiceResponse{ + Name: svc.GetName(), + } + } + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1alphareflectionpb.ListServiceResponse{ + Service: svcs, + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1alphareflectionpb.ErrorResponse{ + ErrorCode: mr.ErrorResponse.GetErrorCode(), + ErrorMessage: mr.ErrorResponse.GetErrorMessage(), + }, + } + } + default: + // no value set + } + return &v1alpha +} + +// V1AlphaToV1Request converts a v1alpha ServerReflectionRequest to a v1. +func V1AlphaToV1Request(v1alpha *v1alphareflectionpb.ServerReflectionRequest) *v1reflectionpb.ServerReflectionRequest { + var v1 v1reflectionpb.ServerReflectionRequest + v1.Host = v1alpha.Host + switch mr := v1alpha.MessageRequest.(type) { + case *v1alphareflectionpb.ServerReflectionRequest_FileByFilename: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileByFilename{ + FileByFilename: mr.FileByFilename, + } + case *v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingSymbol{ + FileContainingSymbol: mr.FileContainingSymbol, + } + case *v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension: + if mr.FileContainingExtension != nil { + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingExtension{ + FileContainingExtension: &v1reflectionpb.ExtensionRequest{ + ContainingType: mr.FileContainingExtension.GetContainingType(), + ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ + AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, + } + case *v1alphareflectionpb.ServerReflectionRequest_ListServices: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_ListServices{ + ListServices: mr.ListServices, + } + default: + // no value set + } + return &v1 +} + +// V1ToV1AlphaRequest converts a v1 ServerReflectionRequest to a v1alpha. +func V1ToV1AlphaRequest(v1 *v1reflectionpb.ServerReflectionRequest) *v1alphareflectionpb.ServerReflectionRequest { + var v1alpha v1alphareflectionpb.ServerReflectionRequest + v1alpha.Host = v1.Host + switch mr := v1.MessageRequest.(type) { + case *v1reflectionpb.ServerReflectionRequest_FileByFilename: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileByFilename{ + FileByFilename: mr.FileByFilename, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol{ + FileContainingSymbol: mr.FileContainingSymbol, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension{ + FileContainingExtension: &v1alphareflectionpb.ExtensionRequest{ + ContainingType: mr.FileContainingExtension.GetContainingType(), + ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), + }, + } + } + case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ + AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, + } + } + case *v1reflectionpb.ServerReflectionRequest_ListServices: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_ListServices{ + ListServices: mr.ListServices, + } + } + default: + // no value set + } + return &v1alpha +} + +// V1AlphaToV1Response converts a v1alpha ServerReflectionResponse to a v1. +func V1AlphaToV1Response(v1alpha *v1alphareflectionpb.ServerReflectionResponse) *v1reflectionpb.ServerReflectionResponse { + var v1 v1reflectionpb.ServerReflectionResponse + v1.ValidHost = v1alpha.ValidHost + if v1alpha.OriginalRequest != nil { + v1.OriginalRequest = V1AlphaToV1Request(v1alpha.OriginalRequest) + } + switch mr := v1alpha.MessageResponse.(type) { + case *v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse: + if mr != nil { + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{ + FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: + if mr != nil { + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ + BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), + ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse: + if mr != nil { + svcs := make([]*v1reflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) + for i, svc := range mr.ListServicesResponse.GetService() { + svcs[i] = &v1reflectionpb.ServiceResponse{ + Name: svc.GetName(), + } + } + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1reflectionpb.ListServiceResponse{ + Service: svcs, + }, + } + } + case *v1alphareflectionpb.ServerReflectionResponse_ErrorResponse: + if mr != nil { + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: mr.ErrorResponse.GetErrorCode(), + ErrorMessage: mr.ErrorResponse.GetErrorMessage(), + }, + } + } + default: + // no value set + } + return &v1 +} diff --git a/vendor/google.golang.org/grpc/reflection/serverreflection.go b/vendor/google.golang.org/grpc/reflection/serverreflection.go index c3b40839..13a94e2d 100644 --- a/vendor/google.golang.org/grpc/reflection/serverreflection.go +++ b/vendor/google.golang.org/grpc/reflection/serverreflection.go @@ -37,19 +37,13 @@ To register server reflection on a gRPC server: package reflection // import "google.golang.org/grpc/reflection" import ( - "io" - "sort" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" + "google.golang.org/grpc/reflection/internal" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" - v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" ) @@ -158,203 +152,9 @@ func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer { if opts.ExtensionResolver == nil { opts.ExtensionResolver = protoregistry.GlobalTypes } - return &serverReflectionServer{ - s: opts.Services, - descResolver: opts.DescriptorResolver, - extResolver: opts.ExtensionResolver, - } -} - -type serverReflectionServer struct { - v1alphareflectiongrpc.UnimplementedServerReflectionServer - s ServiceInfoProvider - descResolver protodesc.Resolver - extResolver ExtensionResolver -} - -// fileDescWithDependencies returns a slice of serialized fileDescriptors in -// wire format ([]byte). The fileDescriptors will include fd and all the -// transitive dependencies of fd with names not in sentFileDescriptors. -func (s *serverReflectionServer) fileDescWithDependencies(fd protoreflect.FileDescriptor, sentFileDescriptors map[string]bool) ([][]byte, error) { - if fd.IsPlaceholder() { - // If the given root file is a placeholder, treat it - // as missing instead of serializing it. - return nil, protoregistry.NotFound - } - var r [][]byte - queue := []protoreflect.FileDescriptor{fd} - for len(queue) > 0 { - currentfd := queue[0] - queue = queue[1:] - if currentfd.IsPlaceholder() { - // Skip any missing files in the dependency graph. - continue - } - if sent := sentFileDescriptors[currentfd.Path()]; len(r) == 0 || !sent { - sentFileDescriptors[currentfd.Path()] = true - fdProto := protodesc.ToFileDescriptorProto(currentfd) - currentfdEncoded, err := proto.Marshal(fdProto) - if err != nil { - return nil, err - } - r = append(r, currentfdEncoded) - } - for i := 0; i < currentfd.Imports().Len(); i++ { - queue = append(queue, currentfd.Imports().Get(i)) - } - } - return r, nil -} - -// fileDescEncodingContainingSymbol finds the file descriptor containing the -// given symbol, finds all of its previously unsent transitive dependencies, -// does marshalling on them, and returns the marshalled result. The given symbol -// can be a type, a service or a method. -func (s *serverReflectionServer) fileDescEncodingContainingSymbol(name string, sentFileDescriptors map[string]bool) ([][]byte, error) { - d, err := s.descResolver.FindDescriptorByName(protoreflect.FullName(name)) - if err != nil { - return nil, err - } - return s.fileDescWithDependencies(d.ParentFile(), sentFileDescriptors) -} - -// fileDescEncodingContainingExtension finds the file descriptor containing -// given extension, finds all of its previously unsent transitive dependencies, -// does marshalling on them, and returns the marshalled result. -func (s *serverReflectionServer) fileDescEncodingContainingExtension(typeName string, extNum int32, sentFileDescriptors map[string]bool) ([][]byte, error) { - xt, err := s.extResolver.FindExtensionByNumber(protoreflect.FullName(typeName), protoreflect.FieldNumber(extNum)) - if err != nil { - return nil, err - } - return s.fileDescWithDependencies(xt.TypeDescriptor().ParentFile(), sentFileDescriptors) -} - -// allExtensionNumbersForTypeName returns all extension numbers for the given type. -func (s *serverReflectionServer) allExtensionNumbersForTypeName(name string) ([]int32, error) { - var numbers []int32 - s.extResolver.RangeExtensionsByMessage(protoreflect.FullName(name), func(xt protoreflect.ExtensionType) bool { - numbers = append(numbers, int32(xt.TypeDescriptor().Number())) - return true - }) - sort.Slice(numbers, func(i, j int) bool { - return numbers[i] < numbers[j] - }) - if len(numbers) == 0 { - // maybe return an error if given type name is not known - if _, err := s.descResolver.FindDescriptorByName(protoreflect.FullName(name)); err != nil { - return nil, err - } - } - return numbers, nil -} - -// listServices returns the names of services this server exposes. -func (s *serverReflectionServer) listServices() []*v1reflectionpb.ServiceResponse { - serviceInfo := s.s.GetServiceInfo() - resp := make([]*v1reflectionpb.ServiceResponse, 0, len(serviceInfo)) - for svc := range serviceInfo { - resp = append(resp, &v1reflectionpb.ServiceResponse{Name: svc}) - } - sort.Slice(resp, func(i, j int) bool { - return resp[i].Name < resp[j].Name - }) - return resp -} - -// ServerReflectionInfo is the reflection service handler. -func (s *serverReflectionServer) ServerReflectionInfo(stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoServer) error { - sentFileDescriptors := make(map[string]bool) - for { - in, err := stream.Recv() - if err == io.EOF { - return nil - } - if err != nil { - return err - } - - out := &v1reflectionpb.ServerReflectionResponse{ - ValidHost: in.Host, - OriginalRequest: in, - } - switch req := in.MessageRequest.(type) { - case *v1reflectionpb.ServerReflectionRequest_FileByFilename: - var b [][]byte - fd, err := s.descResolver.FindFileByPath(req.FileByFilename) - if err == nil { - b, err = s.fileDescWithDependencies(fd, sentFileDescriptors) - } - if err != nil { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1reflectionpb.ErrorResponse{ - ErrorCode: int32(codes.NotFound), - ErrorMessage: err.Error(), - }, - } - } else { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, - } - } - case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: - b, err := s.fileDescEncodingContainingSymbol(req.FileContainingSymbol, sentFileDescriptors) - if err != nil { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1reflectionpb.ErrorResponse{ - ErrorCode: int32(codes.NotFound), - ErrorMessage: err.Error(), - }, - } - } else { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, - } - } - case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: - typeName := req.FileContainingExtension.ContainingType - extNum := req.FileContainingExtension.ExtensionNumber - b, err := s.fileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors) - if err != nil { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1reflectionpb.ErrorResponse{ - ErrorCode: int32(codes.NotFound), - ErrorMessage: err.Error(), - }, - } - } else { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ - FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, - } - } - case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: - extNums, err := s.allExtensionNumbersForTypeName(req.AllExtensionNumbersOfType) - if err != nil { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ - ErrorResponse: &v1reflectionpb.ErrorResponse{ - ErrorCode: int32(codes.NotFound), - ErrorMessage: err.Error(), - }, - } - } else { - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ - AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ - BaseTypeName: req.AllExtensionNumbersOfType, - ExtensionNumber: extNums, - }, - } - } - case *v1reflectionpb.ServerReflectionRequest_ListServices: - out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ - ListServicesResponse: &v1reflectionpb.ListServiceResponse{ - Service: s.listServices(), - }, - } - default: - return status.Errorf(codes.InvalidArgument, "invalid MessageRequest: %v", in.MessageRequest) - } - - if err := stream.Send(out); err != nil { - return err - } + return &internal.ServerReflectionServer{ + S: opts.Services, + DescResolver: opts.DescriptorResolver, + ExtResolver: opts.ExtensionResolver, } } diff --git a/vendor/google.golang.org/grpc/regenerate.sh b/vendor/google.golang.org/grpc/regenerate.sh index a6f26c8a..3edca296 100644 --- a/vendor/google.golang.org/grpc/regenerate.sh +++ b/vendor/google.golang.org/grpc/regenerate.sh @@ -63,7 +63,7 @@ LEGACY_SOURCES=( # Generates only the new gRPC Service symbols SOURCES=( - $(git ls-files --exclude-standard --cached --others "*.proto" | grep -v '^\(profiling/proto/service.proto\|reflection/grpc_reflection_v1alpha/reflection.proto\)$') + $(git ls-files --exclude-standard --cached --others "*.proto" | grep -v '^profiling/proto/service.proto$') ${WORKDIR}/grpc-proto/grpc/gcp/altscontext.proto ${WORKDIR}/grpc-proto/grpc/gcp/handshaker.proto ${WORKDIR}/grpc-proto/grpc/gcp/transport_security_common.proto @@ -93,7 +93,7 @@ Mgrpc/testing/empty.proto=google.golang.org/grpc/interop/grpc_testing for src in ${SOURCES[@]}; do echo "protoc ${src}" - protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS}:${WORKDIR}/out \ + protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS},use_generic_streams_experimental=true:${WORKDIR}/out \ -I"." \ -I${WORKDIR}/grpc-proto \ -I${WORKDIR}/googleapis \ @@ -118,6 +118,6 @@ mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/ # grpc_testing_not_regenerate/*.pb.go are not re-generated, # see grpc_testing_not_regenerate/README.md for details. -rm ${WORKDIR}/out/google.golang.org/grpc/reflection/grpc_testing_not_regenerate/*.pb.go +rm ${WORKDIR}/out/google.golang.org/grpc/reflection/test/grpc_testing_not_regenerate/*.pb.go cp -R ${WORKDIR}/out/google.golang.org/grpc/* . diff --git a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go index b54a3a32..ef3d6ed6 100644 --- a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go @@ -18,9 +18,6 @@ // Package dns implements a dns resolver to be installed as the default resolver // in grpc. -// -// Deprecated: this package is imported by grpc and should not need to be -// imported directly by users. package dns import ( @@ -52,3 +49,12 @@ func SetResolvingTimeout(timeout time.Duration) { func NewBuilder() resolver.Builder { return dns.NewBuilder() } + +// SetMinResolutionInterval sets the default minimum interval at which DNS +// re-resolutions are allowed. This helps to prevent excessive re-resolution. +// +// It must be called only at application startup, before any gRPC calls are +// made. Modifying this value after initialization is not thread-safe. +func SetMinResolutionInterval(d time.Duration) { + dns.MinResolutionInterval = d +} diff --git a/vendor/google.golang.org/grpc/resolver_wrapper.go b/vendor/google.golang.org/grpc/resolver_wrapper.go index 9dcc9780..c5fb4523 100644 --- a/vendor/google.golang.org/grpc/resolver_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_wrapper.go @@ -171,7 +171,7 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { // ParseServiceConfig is called by resolver implementations to parse a JSON // representation of the service config. func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult { - return parseServiceConfig(scJSON) + return parseServiceConfig(scJSON, ccr.cc.dopts.maxCallAttempts) } // addChannelzTraceEvent adds a channelz trace event containing the new diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 998e251d..fdd49e6e 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -964,7 +964,7 @@ func setCallInfoCodec(c *callInfo) error { // The SupportPackageIsVersion variables are referenced from generated protocol // buffer files to ensure compatibility with the gRPC version used. The latest -// support package version is 7. +// support package version is 9. // // Older versions are kept for compatibility. // @@ -976,6 +976,7 @@ const ( SupportPackageIsVersion6 = true SupportPackageIsVersion7 = true SupportPackageIsVersion8 = true + SupportPackageIsVersion9 = true ) const grpcUA = "grpc-go/" + Version diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index fd4558da..89f8e479 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -527,12 +527,22 @@ func ConnectionTimeout(d time.Duration) ServerOption { }) } +// MaxHeaderListSizeServerOption is a ServerOption that sets the max +// (uncompressed) size of header list that the server is prepared to accept. +type MaxHeaderListSizeServerOption struct { + MaxHeaderListSize uint32 +} + +func (o MaxHeaderListSizeServerOption) apply(so *serverOptions) { + so.maxHeaderListSize = &o.MaxHeaderListSize +} + // MaxHeaderListSize returns a ServerOption that sets the max (uncompressed) size // of header list that the server is prepared to accept. func MaxHeaderListSize(s uint32) ServerOption { - return newFuncServerOption(func(o *serverOptions) { - o.maxHeaderListSize = &s - }) + return MaxHeaderListSizeServerOption{ + MaxHeaderListSize: s, + } } // HeaderTableSize returns a ServerOption that sets the size of dynamic diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 2b35c5d2..2671c5ef 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -26,6 +26,7 @@ import ( "time" "google.golang.org/grpc/balancer" + "google.golang.org/grpc/balancer/pickfirst" "google.golang.org/grpc/codes" "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/balancer/gracefulswitch" @@ -163,16 +164,18 @@ type jsonSC struct { } func init() { - internal.ParseServiceConfig = parseServiceConfig + internal.ParseServiceConfig = func(js string) *serviceconfig.ParseResult { + return parseServiceConfig(js, defaultMaxCallAttempts) + } } -func parseServiceConfig(js string) *serviceconfig.ParseResult { +func parseServiceConfig(js string, maxAttempts int) *serviceconfig.ParseResult { if len(js) == 0 { return &serviceconfig.ParseResult{Err: fmt.Errorf("no JSON service config provided")} } var rsc jsonSC err := json.Unmarshal([]byte(js), &rsc) if err != nil { - logger.Warningf("grpc: unmarshaling service config %s: %v", js, err) + logger.Warningf("grpc: unmarshalling service config %s: %v", js, err) return &serviceconfig.ParseResult{Err: err} } sc := ServiceConfig{ @@ -183,12 +186,12 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { } c := rsc.LoadBalancingConfig if c == nil { - name := PickFirstBalancerName + name := pickfirst.Name if rsc.LoadBalancingPolicy != nil { name = *rsc.LoadBalancingPolicy } if balancer.Get(name) == nil { - name = PickFirstBalancerName + name = pickfirst.Name } cfg := []map[string]any{{name: struct{}{}}} strCfg, err := json.Marshal(cfg) @@ -218,8 +221,8 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { WaitForReady: m.WaitForReady, Timeout: (*time.Duration)(m.Timeout), } - if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil { - logger.Warningf("grpc: unmarshaling service config %s: %v", js, err) + if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy, maxAttempts); err != nil { + logger.Warningf("grpc: unmarshalling service config %s: %v", js, err) return &serviceconfig.ParseResult{Err: err} } if m.MaxRequestMessageBytes != nil { @@ -239,13 +242,13 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { for i, n := range *m.Name { path, err := n.generatePath() if err != nil { - logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err) + logger.Warningf("grpc: error unmarshalling service config %s due to methodConfig[%d]: %v", js, i, err) return &serviceconfig.ParseResult{Err: err} } if _, ok := paths[path]; ok { err = errDuplicatedName - logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err) + logger.Warningf("grpc: error unmarshalling service config %s due to methodConfig[%d]: %v", js, i, err) return &serviceconfig.ParseResult{Err: err} } paths[path] = struct{}{} @@ -264,7 +267,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { return &serviceconfig.ParseResult{Config: &sc} } -func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPolicy, err error) { +func convertRetryPolicy(jrp *jsonRetryPolicy, maxAttempts int) (p *internalserviceconfig.RetryPolicy, err error) { if jrp == nil { return nil, nil } @@ -278,17 +281,16 @@ func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPol return nil, nil } + if jrp.MaxAttempts < maxAttempts { + maxAttempts = jrp.MaxAttempts + } rp := &internalserviceconfig.RetryPolicy{ - MaxAttempts: jrp.MaxAttempts, + MaxAttempts: maxAttempts, InitialBackoff: time.Duration(jrp.InitialBackoff), MaxBackoff: time.Duration(jrp.MaxBackoff), BackoffMultiplier: jrp.BackoffMultiplier, RetryableStatusCodes: make(map[codes.Code]bool), } - if rp.MaxAttempts > 5 { - // TODO(retry): Make the max maxAttempts configurable. - rp.MaxAttempts = 5 - } for _, code := range jrp.RetryableStatusCodes { rp.RetryableStatusCodes[code] = true } diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index 4ab70e2d..fdb0bd65 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -73,9 +73,12 @@ func (*PickerUpdated) isRPCStats() {} type InPayload struct { // Client is true if this InPayload is from client side. Client bool - // Payload is the payload with original type. + // Payload is the payload with original type. This may be modified after + // the call to HandleRPC which provides the InPayload returns and must be + // copied if needed later. Payload any // Data is the serialized message payload. + // Deprecated: Data will be removed in the next release. Data []byte // Length is the size of the uncompressed payload data. Does not include any @@ -143,9 +146,12 @@ func (s *InTrailer) isRPCStats() {} type OutPayload struct { // Client is true if this OutPayload is from client side. Client bool - // Payload is the payload with original type. + // Payload is the payload with original type. This may be modified after + // the call to HandleRPC which provides the OutPayload returns and must be + // copied if needed later. Payload any // Data is the serialized message payload. + // Deprecated: Data will be removed in the next release. Data []byte // Length is the size of the uncompressed payload data. Does not include any // framing (gRPC or HTTP/2). diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index d939ffc6..8051ef5b 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -23,6 +23,7 @@ import ( "errors" "io" "math" + "math/rand" "strconv" "sync" "time" @@ -34,7 +35,6 @@ import ( "google.golang.org/grpc/internal/balancerload" "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/channelz" - "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/internal/grpcutil" imetadata "google.golang.org/grpc/internal/metadata" iresolver "google.golang.org/grpc/internal/resolver" @@ -516,6 +516,7 @@ func (a *csAttempt) newStream() error { return toRPCErr(nse.Err) } a.s = s + a.ctx = s.Context() a.p = &parser{r: s, recvBufferPool: a.cs.cc.dopts.recvBufferPool} return nil } @@ -698,7 +699,7 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) { if max := float64(rp.MaxBackoff); cur > max { cur = max } - dur = time.Duration(grpcrand.Int63n(int64(cur))) + dur = time.Duration(rand.Int63n(int64(cur))) cs.numRetriesSincePushback++ } diff --git a/vendor/google.golang.org/grpc/stream_interfaces.go b/vendor/google.golang.org/grpc/stream_interfaces.go new file mode 100644 index 00000000..8b813529 --- /dev/null +++ b/vendor/google.golang.org/grpc/stream_interfaces.go @@ -0,0 +1,152 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed 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 grpc + +// ServerStreamingClient represents the client side of a server-streaming (one +// request, many responses) RPC. It is generic over the type of the response +// message. It is used in generated code. +type ServerStreamingClient[Res any] interface { + Recv() (*Res, error) + ClientStream +} + +// ServerStreamingServer represents the server side of a server-streaming (one +// request, many responses) RPC. It is generic over the type of the response +// message. It is used in generated code. +type ServerStreamingServer[Res any] interface { + Send(*Res) error + ServerStream +} + +// ClientStreamingClient represents the client side of a client-streaming (many +// requests, one response) RPC. It is generic over both the type of the request +// message stream and the type of the unary response message. It is used in +// generated code. +type ClientStreamingClient[Req any, Res any] interface { + Send(*Req) error + CloseAndRecv() (*Res, error) + ClientStream +} + +// ClientStreamingServer represents the server side of a client-streaming (many +// requests, one response) RPC. It is generic over both the type of the request +// message stream and the type of the unary response message. It is used in +// generated code. +type ClientStreamingServer[Req any, Res any] interface { + Recv() (*Req, error) + SendAndClose(*Res) error + ServerStream +} + +// BidiStreamingClient represents the client side of a bidirectional-streaming +// (many requests, many responses) RPC. It is generic over both the type of the +// request message stream and the type of the response message stream. It is +// used in generated code. +type BidiStreamingClient[Req any, Res any] interface { + Send(*Req) error + Recv() (*Res, error) + ClientStream +} + +// BidiStreamingServer represents the server side of a bidirectional-streaming +// (many requests, many responses) RPC. It is generic over both the type of the +// request message stream and the type of the response message stream. It is +// used in generated code. +type BidiStreamingServer[Req any, Res any] interface { + Recv() (*Req, error) + Send(*Res) error + ServerStream +} + +// GenericClientStream implements the ServerStreamingClient, ClientStreamingClient, +// and BidiStreamingClient interfaces. It is used in generated code. +type GenericClientStream[Req any, Res any] struct { + ClientStream +} + +var _ ServerStreamingClient[string] = (*GenericClientStream[int, string])(nil) +var _ ClientStreamingClient[int, string] = (*GenericClientStream[int, string])(nil) +var _ BidiStreamingClient[int, string] = (*GenericClientStream[int, string])(nil) + +// Send pushes one message into the stream of requests to be consumed by the +// server. The type of message which can be sent is determined by the Req type +// parameter of the GenericClientStream receiver. +func (x *GenericClientStream[Req, Res]) Send(m *Req) error { + return x.ClientStream.SendMsg(m) +} + +// Recv reads one message from the stream of responses generated by the server. +// The type of the message returned is determined by the Res type parameter +// of the GenericClientStream receiver. +func (x *GenericClientStream[Req, Res]) Recv() (*Res, error) { + m := new(Res) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// CloseAndRecv closes the sending side of the stream, then receives the unary +// response from the server. The type of message which it returns is determined +// by the Res type parameter of the GenericClientStream receiver. +func (x *GenericClientStream[Req, Res]) CloseAndRecv() (*Res, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new(Res) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// GenericServerStream implements the ServerStreamingServer, ClientStreamingServer, +// and BidiStreamingServer interfaces. It is used in generated code. +type GenericServerStream[Req any, Res any] struct { + ServerStream +} + +var _ ServerStreamingServer[string] = (*GenericServerStream[int, string])(nil) +var _ ClientStreamingServer[int, string] = (*GenericServerStream[int, string])(nil) +var _ BidiStreamingServer[int, string] = (*GenericServerStream[int, string])(nil) + +// Send pushes one message into the stream of responses to be consumed by the +// client. The type of message which can be sent is determined by the Res +// type parameter of the serverStreamServer receiver. +func (x *GenericServerStream[Req, Res]) Send(m *Res) error { + return x.ServerStream.SendMsg(m) +} + +// SendAndClose pushes the unary response to the client. The type of message +// which can be sent is determined by the Res type parameter of the +// clientStreamServer receiver. +func (x *GenericServerStream[Req, Res]) SendAndClose(m *Res) error { + return x.ServerStream.SendMsg(m) +} + +// Recv reads one message from the stream of requests generated by the client. +// The type of the message returned is determined by the Req type parameter +// of the clientStreamServer receiver. +func (x *GenericServerStream[Req, Res]) Recv() (*Req, error) { + m := new(Req) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 2556f758..bafaef99 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.63.2" +const Version = "1.65.0" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh deleted file mode 100644 index 7e6b92e4..00000000 --- a/vendor/google.golang.org/grpc/vet.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/bin/bash - -set -ex # Exit on error; debugging enabled. -set -o pipefail # Fail a pipe if any sub-command fails. - -# not makes sure the command passed to it does not exit with a return code of 0. -not() { - # This is required instead of the earlier (! $COMMAND) because subshells and - # pipefail don't work the same on Darwin as in Linux. - ! "$@" -} - -die() { - echo "$@" >&2 - exit 1 -} - -fail_on_output() { - tee /dev/stderr | not read -} - -# Check to make sure it's safe to modify the user's git repo. -git status --porcelain | fail_on_output - -# Undo any edits made by this script. -cleanup() { - git reset --hard HEAD -} -trap cleanup EXIT - -PATH="${HOME}/go/bin:${GOROOT}/bin:${PATH}" -go version - -if [[ "$1" = "-install" ]]; then - # Install the pinned versions as defined in module tools. - pushd ./test/tools - go install \ - golang.org/x/tools/cmd/goimports \ - honnef.co/go/tools/cmd/staticcheck \ - github.com/client9/misspell/cmd/misspell - popd - if [[ -z "${VET_SKIP_PROTO}" ]]; then - if [[ "${GITHUB_ACTIONS}" = "true" ]]; then - PROTOBUF_VERSION=25.2 # a.k.a. v4.22.0 in pb.go files. - PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip - pushd /home/runner/go - wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} - unzip ${PROTOC_FILENAME} - bin/protoc --version - popd - elif not which protoc > /dev/null; then - die "Please install protoc into your path" - fi - fi - exit 0 -elif [[ "$#" -ne 0 ]]; then - die "Unknown argument(s): $*" -fi - -# - Check that generated proto files are up to date. -if [[ -z "${VET_SKIP_PROTO}" ]]; then - make proto && git status --porcelain 2>&1 | fail_on_output || \ - (git status; git --no-pager diff; exit 1) -fi - -if [[ -n "${VET_ONLY_PROTO}" ]]; then - exit 0 -fi - -# - Ensure all source files contain a copyright message. -# (Done in two parts because Darwin "git grep" has broken support for compound -# exclusion matches.) -(grep -L "DO NOT EDIT" $(git grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)" -- '*.go') || true) | fail_on_output - -# - Make sure all tests in grpc and grpc/test use leakcheck via Teardown. -not grep 'func Test[^(]' *_test.go -not grep 'func Test[^(]' test/*.go - -# - Check for typos in test function names -git grep 'func (s) ' -- "*_test.go" | not grep -v 'func (s) Test' -git grep 'func [A-Z]' -- "*_test.go" | not grep -v 'func Test\|Benchmark\|Example' - -# - Do not import x/net/context. -not git grep -l 'x/net/context' -- "*.go" - -# - Do not use time.After except in tests. It has the potential to leak the -# timer since there is no way to stop it early. -git grep -l 'time.After(' -- "*.go" | not grep -v '_test.go\|test_utils\|testutils' - -# - Do not import math/rand for real library code. Use internal/grpcrand for -# thread safety. -git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test' - -# - Do not use "interface{}"; use "any" instead. -git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc\|grpc_testing_not_regenerate' - -# - Do not call grpclog directly. Use grpclog.Component instead. -git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' - -# - Ensure all ptypes proto packages are renamed when importing. -not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" - -# - Ensure all usages of grpc_testing package are renamed when importing. -not git grep "\(import \|^\s*\)\"google.golang.org/grpc/interop/grpc_testing" -- "*.go" - -# - Ensure all xds proto imports are renamed to *pb or *grpc. -git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "' - -misspell -error . - -# - gofmt, goimports, go vet, go mod tidy. -# Perform these checks on each module inside gRPC. -for MOD_FILE in $(find . -name 'go.mod'); do - MOD_DIR=$(dirname ${MOD_FILE}) - pushd ${MOD_DIR} - go vet -all ./... | fail_on_output - gofmt -s -d -l . 2>&1 | fail_on_output - goimports -l . 2>&1 | not grep -vE "\.pb\.go" - - go mod tidy -compat=1.19 - git status --porcelain 2>&1 | fail_on_output || \ - (git status; git --no-pager diff; exit 1) - popd -done - -# - Collection of static analysis checks -SC_OUT="$(mktemp)" -staticcheck -go 1.19 -checks 'all' ./... > "${SC_OUT}" || true - -# Error for anything other than checks that need exclusions. -grep -v "(ST1000)" "${SC_OUT}" | grep -v "(SA1019)" | grep -v "(ST1003)" | not grep -v "(ST1019)\|\(other import of\)" - -# Exclude underscore checks for generated code. -grep "(ST1003)" "${SC_OUT}" | not grep -v '\(.pb.go:\)\|\(code_string_test.go:\)\|\(grpc_testing_not_regenerate\)' - -# Error for duplicate imports not including grpc protos. -grep "(ST1019)\|\(other import of\)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused -channelz/grpc_channelz_v1" -go-control-plane/envoy -grpclb/grpc_lb_v1" -health/grpc_health_v1" -interop/grpc_testing" -orca/v3" -proto/grpc_gcp" -proto/grpc_lookup_v1" -reflection/grpc_reflection_v1" -reflection/grpc_reflection_v1alpha" -XXXXX PleaseIgnoreUnused' - -# Error for any package comments not in generated code. -grep "(ST1000)" "${SC_OUT}" | not grep -v "\.pb\.go:" - -# Only ignore the following deprecated types/fields/functions and exclude -# generated code. -grep "(SA1019)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused -XXXXX Protobuf related deprecation errors: -"github.com/golang/protobuf -.pb.go: -grpc_testing_not_regenerate -: ptypes. -proto.RegisterType -XXXXX gRPC internal usage deprecation errors: -"google.golang.org/grpc -: grpc. -: v1alpha. -: v1alphareflectionpb. -BalancerAttributes is deprecated: -CredsBundle is deprecated: -Metadata is deprecated: use Attributes instead. -NewSubConn is deprecated: -OverrideServerName is deprecated: -RemoveSubConn is deprecated: -SecurityVersion is deprecated: -Target is deprecated: Use the Target field in the BuildOptions instead. -UpdateAddresses is deprecated: -UpdateSubConnState is deprecated: -balancer.ErrTransientFailure is deprecated: -grpc/reflection/v1alpha/reflection.proto -SwitchTo is deprecated: -XXXXX xDS deprecated fields we support -.ExactMatch -.PrefixMatch -.SafeRegexMatch -.SuffixMatch -GetContainsMatch -GetExactMatch -GetMatchSubjectAltNames -GetPrefixMatch -GetSafeRegexMatch -GetSuffixMatch -GetTlsCertificateCertificateProviderInstance -GetValidationContextCertificateProviderInstance -XXXXX PleaseIgnoreUnused' - -echo SUCCESS diff --git a/vendor/modules.txt b/vendor/modules.txt index c45cd868..ee26bdb0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -32,7 +32,7 @@ github.com/caarlos0/env/v6 # github.com/cenkalti/backoff/v4 v4.3.0 ## explicit; go 1.18 github.com/cenkalti/backoff/v4 -# github.com/cespare/xxhash/v2 v2.2.0 +# github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 # github.com/cilium/ebpf v0.15.0 @@ -568,7 +568,7 @@ go.opentelemetry.io/proto/otlp/trace/v1 # go.uber.org/atomic v1.9.0 ## explicit; go 1.13 go.uber.org/atomic -# golang.org/x/crypto v0.22.0 +# golang.org/x/crypto v0.23.0 ## explicit; go 1.18 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b @@ -579,7 +579,7 @@ golang.org/x/crypto/curve25519/internal/field # golang.org/x/exp v0.0.0-20230905200255-921286631fa9 ## explicit; go 1.20 golang.org/x/exp/constraints -# golang.org/x/net v0.24.0 +# golang.org/x/net v0.25.0 ## explicit; go 1.18 golang.org/x/net/context golang.org/x/net/html @@ -595,7 +595,7 @@ golang.org/x/net/proxy golang.org/x/net/publicsuffix golang.org/x/net/trace golang.org/x/net/websocket -# golang.org/x/oauth2 v0.18.0 +# golang.org/x/oauth2 v0.20.0 ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/clientcredentials @@ -607,10 +607,10 @@ golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.19.0 +# golang.org/x/term v0.20.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.14.0 +# golang.org/x/text v0.15.0 ## explicit; go 1.18 golang.org/x/text/secure/bidirule golang.org/x/text/transform @@ -619,30 +619,22 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.5.0 ## explicit; go 1.18 golang.org/x/time/rate -# google.golang.org/appengine v1.6.8 -## explicit; go 1.11 -google.golang.org/appengine/internal -google.golang.org/appengine/internal/base -google.golang.org/appengine/internal/datastore -google.golang.org/appengine/internal/log -google.golang.org/appengine/internal/remote_api -google.golang.org/appengine/internal/urlfetch -google.golang.org/appengine/urlfetch -# google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 -## explicit; go 1.19 +# google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 +## explicit; go 1.20 google.golang.org/genproto/googleapis/api/httpbody -# google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be -## explicit; go 1.19 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 +## explicit; go 1.20 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.63.2 -## explicit; go 1.19 +# google.golang.org/grpc v1.65.0 +## explicit; go 1.21 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff google.golang.org/grpc/balancer google.golang.org/grpc/balancer/base google.golang.org/grpc/balancer/grpclb/state +google.golang.org/grpc/balancer/pickfirst google.golang.org/grpc/balancer/roundrobin google.golang.org/grpc/binarylog/grpc_binarylog_v1 google.golang.org/grpc/channelz @@ -665,7 +657,6 @@ google.golang.org/grpc/internal/channelz google.golang.org/grpc/internal/credentials google.golang.org/grpc/internal/envconfig google.golang.org/grpc/internal/grpclog -google.golang.org/grpc/internal/grpcrand google.golang.org/grpc/internal/grpcsync google.golang.org/grpc/internal/grpcutil google.golang.org/grpc/internal/idle @@ -687,6 +678,7 @@ google.golang.org/grpc/peer google.golang.org/grpc/reflection google.golang.org/grpc/reflection/grpc_reflection_v1 google.golang.org/grpc/reflection/grpc_reflection_v1alpha +google.golang.org/grpc/reflection/internal google.golang.org/grpc/resolver google.golang.org/grpc/resolver/dns google.golang.org/grpc/serviceconfig -- GitLab