From 75b1a21ea06aaedaf726c4614889b7067f355568 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Wed, 4 Sep 2024 13:14:47 +0900 Subject: [PATCH 01/12] =?UTF-8?q?=E2=9C=A8=20impl=20net/url.Parse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../02_simple/federation/federation.pb.go | 399 +++++++++--------- .../federation_grpc_federation.pb.go | 145 ++++--- _examples/02_simple/main_test.go | 2 + .../proto/federation/federation.proto | 2 + grpc/federation/cel/lib.go | 1 + grpc/federation/cel/url.go | 292 +++++++++++++ grpc/federation/cel/url.pb.go | 330 +++++++++++++++ grpc/federation/cel/url_test.go | 82 ++++ proto/grpc/federation/url.proto | 27 ++ 9 files changed, 1038 insertions(+), 242 deletions(-) create mode 100644 grpc/federation/cel/url.go create mode 100644 grpc/federation/cel/url.pb.go create mode 100644 grpc/federation/cel/url_test.go create mode 100644 proto/grpc/federation/url.proto diff --git a/_examples/02_simple/federation/federation.pb.go b/_examples/02_simple/federation/federation.pb.go index 25ec797a..894f3cc8 100644 --- a/_examples/02_simple/federation/federation.pb.go +++ b/_examples/02_simple/federation/federation.pb.go @@ -206,6 +206,7 @@ type GetPostResponse struct { NullTimestamp3 *timestamppb.Timestamp `protobuf:"bytes,30,opt,name=null_timestamp3,json=nullTimestamp3,proto3" json:"null_timestamp3,omitempty"` JpLoc string `protobuf:"bytes,31,opt,name=jp_loc,json=jpLoc,proto3" json:"jp_loc,omitempty"` StringsJoin string `protobuf:"bytes,32,opt,name=strings_join,json=stringsJoin,proto3" json:"strings_join,omitempty"` + UrlUserName string `protobuf:"bytes,33,opt,name=url_user_name,json=urlUserName,proto3" json:"url_user_name,omitempty"` } func (x *GetPostResponse) Reset() { @@ -464,6 +465,13 @@ func (x *GetPostResponse) GetStringsJoin() string { return "" } +func (x *GetPostResponse) GetUrlUserName() string { + if x != nil { + return x.UrlUserName + } + return "" +} + type A struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1168,7 +1176,7 @@ var file_federation_federation_proto_rawDesc = []byte{ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xd7, 0x1d, 0x0a, 0x0f, 0x47, 0x65, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xe8, 0x1e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x42, 0x09, 0x9a, @@ -1346,207 +1354,216 @@ var file_federation_federation_proto_rawDesc = []byte{ 0x12, 0x34, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0x9a, 0x4a, 0x0e, 0x12, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, + 0x67, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x75, 0x72, 0x6c, 0x5f, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0x9a, + 0x4a, 0x17, 0x12, 0x15, 0x75, 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x52, 0x0b, 0x75, 0x72, 0x6c, 0x55, 0x73, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x3a, 0xfd, 0x06, 0x9a, 0x4a, 0xf9, 0x06, 0x0a, 0x1a, 0x0a, 0x04, 0x70, 0x6f, + 0x02, 0x38, 0x01, 0x3a, 0xce, 0x07, 0x9a, 0x4a, 0xca, 0x07, 0x0a, 0x1a, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x6a, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x04, 0x24, 0x2e, 0x69, 0x64, 0x0a, 0x42, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5a, 0x32, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x5b, 0x27, 0x61, 0x27, 0x2c, 0x20, 0x27, 0x62, 0x27, 0x2c, 0x20, - 0x27, 0x63, 0x27, 0x5d, 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x59, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x65, 0x5a, 0x51, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x28, 0x32, 0x30, - 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x32, 0x35, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, - 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x55, - 0x54, 0x43, 0x28, 0x29, 0x29, 0x0a, 0x3a, 0x0a, 0x0b, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5a, 0x2b, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x28, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x75, 0x6e, 0x69, 0x78, 0x28, 0x29, - 0x29, 0x0a, 0x33, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x5a, - 0x25, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x28, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x0a, 0x3b, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x5a, 0x33, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x75, 0x75, 0x69, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x46, - 0x72, 0x6f, 0x6d, 0x52, 0x61, 0x6e, 0x64, 0x28, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x61, - 0x6e, 0x64, 0x29, 0x0a, 0x36, 0x0a, 0x03, 0x6c, 0x6f, 0x63, 0x5a, 0x2f, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x27, 0x41, - 0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x27, 0x29, 0x0a, 0x45, 0x0a, 0x07, 0x6a, - 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x3a, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x64, 0x61, 0x74, - 0x65, 0x28, 0x32, 0x30, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x32, 0x35, 0x2c, 0x20, - 0x31, 0x32, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6c, 0x6f, - 0x63, 0x29, 0x0a, 0x38, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x5a, 0x2e, 0x67, 0x72, - 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x28, - 0x29, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x31, 0x27, 0x5d, 0x5b, 0x30, 0x5d, 0x0a, 0x08, 0x0a, 0x01, - 0x61, 0x6a, 0x03, 0x0a, 0x01, 0x41, 0x0a, 0x2b, 0x0a, 0x0d, 0x73, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5a, 0x1a, 0x5b, 0x34, 0x2c, 0x20, 0x31, 0x2c, 0x20, - 0x33, 0x2c, 0x20, 0x32, 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x41, 0x73, 0x63, 0x28, 0x76, 0x2c, - 0x20, 0x76, 0x29, 0x0a, 0x95, 0x01, 0x0a, 0x0c, 0x73, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x5a, 0x84, 0x01, 0x5b, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, - 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x61, 0x64, - 0x64, 0x72, 0x31, 0x3a, 0x27, 0x61, 0x27, 0x7d, 0x7d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x49, 0x74, 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x73, - 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x7b, 0x61, 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x62, 0x27, 0x7d, 0x7d, 0x5d, 0x2e, 0x73, 0x6f, - 0x72, 0x74, 0x44, 0x65, 0x73, 0x63, 0x28, 0x76, 0x2c, 0x20, 0x76, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x31, 0x29, 0x0a, 0x25, 0x0a, 0x09, 0x6d, - 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x18, 0x7b, 0x31, 0x3a, 0x20, 0x27, 0x61, - 0x27, 0x2c, 0x20, 0x32, 0x3a, 0x20, 0x27, 0x62, 0x27, 0x2c, 0x20, 0x33, 0x3a, 0x20, 0x27, 0x63, - 0x27, 0x7d, 0x0a, 0x12, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5a, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x0a, 0x4b, 0x5a, 0x49, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x69, 0x6e, - 0x66, 0x6f, 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, 0x70, 0x6f, - 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x27, 0x3a, 0x20, 0x70, 0x6f, 0x73, - 0x74, 0x7d, 0x29, 0x22, 0xdf, 0x03, 0x0a, 0x01, 0x41, 0x12, 0x25, 0x0a, 0x01, 0x62, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x42, 0x06, 0x9a, 0x4a, 0x03, 0x12, 0x01, 0x62, 0x52, 0x01, 0x62, - 0x1a, 0xa1, 0x03, 0x0a, 0x01, 0x42, 0x12, 0x2d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, + 0x27, 0x63, 0x27, 0x5d, 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x4f, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x5a, 0x48, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x75, 0x72, 0x6c, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x3a, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x27, 0x29, 0x0a, 0x59, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x65, 0x5a, 0x51, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x28, 0x32, + 0x30, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x32, 0x35, 0x2c, 0x20, 0x31, 0x32, 0x2c, + 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x55, 0x54, 0x43, 0x28, 0x29, 0x29, 0x0a, 0x3a, 0x0a, 0x0b, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5a, 0x2b, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x28, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x75, 0x6e, 0x69, 0x78, 0x28, + 0x29, 0x29, 0x0a, 0x33, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x64, + 0x5a, 0x25, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x28, 0x72, 0x61, 0x6e, 0x64, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x0a, 0x3b, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x5a, + 0x33, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x75, 0x75, 0x69, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x61, 0x6e, 0x64, 0x28, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, + 0x61, 0x6e, 0x64, 0x29, 0x0a, 0x36, 0x0a, 0x03, 0x6c, 0x6f, 0x63, 0x5a, 0x2f, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x27, + 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x27, 0x29, 0x0a, 0x45, 0x0a, 0x07, + 0x6a, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x3a, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x64, 0x61, + 0x74, 0x65, 0x28, 0x32, 0x30, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x32, 0x35, 0x2c, + 0x20, 0x31, 0x32, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6c, + 0x6f, 0x63, 0x29, 0x0a, 0x38, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x5a, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, + 0x28, 0x29, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x31, 0x27, 0x5d, 0x5b, 0x30, 0x5d, 0x0a, 0x08, 0x0a, + 0x01, 0x61, 0x6a, 0x03, 0x0a, 0x01, 0x41, 0x0a, 0x2b, 0x0a, 0x0d, 0x73, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5a, 0x1a, 0x5b, 0x34, 0x2c, 0x20, 0x31, 0x2c, + 0x20, 0x33, 0x2c, 0x20, 0x32, 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x41, 0x73, 0x63, 0x28, 0x76, + 0x2c, 0x20, 0x76, 0x29, 0x0a, 0x95, 0x01, 0x0a, 0x0c, 0x73, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5a, 0x84, 0x01, 0x5b, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, + 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x61, + 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x61, 0x27, 0x7d, 0x7d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x62, 0x27, 0x7d, 0x7d, 0x5d, 0x2e, 0x73, + 0x6f, 0x72, 0x74, 0x44, 0x65, 0x73, 0x63, 0x28, 0x76, 0x2c, 0x20, 0x76, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x31, 0x29, 0x0a, 0x25, 0x0a, 0x09, + 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x18, 0x7b, 0x31, 0x3a, 0x20, 0x27, + 0x61, 0x27, 0x2c, 0x20, 0x32, 0x3a, 0x20, 0x27, 0x62, 0x27, 0x2c, 0x20, 0x33, 0x3a, 0x20, 0x27, + 0x63, 0x27, 0x7d, 0x0a, 0x12, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5a, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x0a, 0x4b, 0x5a, 0x49, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x69, + 0x6e, 0x66, 0x6f, 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, 0x70, + 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x27, 0x3a, 0x20, 0x70, 0x6f, + 0x73, 0x74, 0x7d, 0x29, 0x22, 0xdf, 0x03, 0x0a, 0x01, 0x41, 0x12, 0x25, 0x0a, 0x01, 0x62, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x42, 0x06, 0x9a, 0x4a, 0x03, 0x12, 0x01, 0x62, 0x52, 0x01, + 0x62, 0x1a, 0xa1, 0x03, 0x0a, 0x01, 0x42, 0x12, 0x2d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, 0x03, 0x66, 0x6f, + 0x6f, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x2d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, 0x03, 0x66, 0x6f, 0x6f, - 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x2d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, 0x03, 0x62, 0x61, 0x72, 0x52, - 0x03, 0x62, 0x61, 0x72, 0x1a, 0x24, 0x0a, 0x01, 0x43, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x9a, 0x4a, 0x08, 0x12, 0x06, 0x24, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x97, 0x02, 0x9a, 0x4a, 0x93, - 0x02, 0x0a, 0x1d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x6a, 0x16, 0x0a, 0x05, 0x41, 0x2e, 0x42, 0x2e, - 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, 0x66, 0x6f, 0x6f, 0x27, - 0x0a, 0x1d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x6a, 0x16, 0x0a, 0x05, 0x41, 0x2e, 0x42, 0x2e, 0x43, - 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, 0x62, 0x61, 0x72, 0x27, 0x0a, - 0x89, 0x01, 0x12, 0x11, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, - 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x5a, 0x74, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x28, - 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x27, 0x3a, 0x20, 0x5b, 0x66, 0x6f, 0x6f, 0x2c, 0x20, 0x62, 0x61, 0x72, 0x5d, - 0x2c, 0x20, 0x27, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x27, 0x3a, - 0x20, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2c, 0x20, 0x27, 0x62, - 0x61, 0x72, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x7d, 0x7d, 0x29, 0x0a, 0x47, 0x5a, 0x45, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, - 0x6f, 0x67, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x27, 0x62, - 0x61, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x7d, 0x29, 0x3a, 0x0f, 0x9a, 0x4a, 0x0c, 0x0a, 0x0a, 0x0a, 0x01, 0x62, 0x6a, 0x05, - 0x0a, 0x03, 0x41, 0x2e, 0x42, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2f, - 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x66, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x09, - 0x9a, 0x4a, 0x06, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x3a, - 0x6d, 0x9a, 0x4a, 0x6a, 0x0a, 0x3c, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x35, 0x0a, 0x18, 0x70, - 0x6f, 0x73, 0x74, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, - 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x04, 0x24, - 0x2e, 0x69, 0x64, 0x1a, 0x03, 0x31, 0x30, 0x73, 0x22, 0x08, 0x0a, 0x06, 0x0a, 0x02, 0x32, 0x73, - 0x10, 0x03, 0x0a, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x5a, 0x08, 0x72, 0x65, - 0x73, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x0a, 0x16, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x6a, 0x0e, - 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x06, 0x1a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x22, 0xc8, - 0x04, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x66, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, - 0x65, 0x6d, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x06, - 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, - 0x74, 0x74, 0x72, 0x41, 0x48, 0x00, 0x52, 0x05, 0x61, 0x74, 0x74, 0x72, 0x41, 0x12, 0x26, 0x0a, - 0x01, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x42, - 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x50, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x2f, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x72, 0x41, + 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, 0x03, 0x62, 0x61, 0x72, + 0x52, 0x03, 0x62, 0x61, 0x72, 0x1a, 0x24, 0x0a, 0x01, 0x43, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x9a, 0x4a, 0x08, 0x12, 0x06, 0x24, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x97, 0x02, 0x9a, 0x4a, + 0x93, 0x02, 0x0a, 0x1d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x6a, 0x16, 0x0a, 0x05, 0x41, 0x2e, 0x42, + 0x2e, 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, 0x66, 0x6f, 0x6f, + 0x27, 0x0a, 0x1d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x6a, 0x16, 0x0a, 0x05, 0x41, 0x2e, 0x42, 0x2e, + 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, 0x62, 0x61, 0x72, 0x27, + 0x0a, 0x89, 0x01, 0x12, 0x11, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x5a, 0x74, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x69, 0x6e, 0x66, 0x6f, + 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x27, 0x3a, 0x20, 0x5b, 0x66, 0x6f, 0x6f, 0x2c, 0x20, 0x62, 0x61, 0x72, + 0x5d, 0x2c, 0x20, 0x27, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x27, + 0x3a, 0x20, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2c, 0x20, 0x27, + 0x62, 0x61, 0x72, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x7d, 0x7d, 0x29, 0x0a, 0x47, 0x5a, 0x45, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x27, + 0x62, 0x61, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x7d, 0x29, 0x3a, 0x0f, 0x9a, 0x4a, 0x0c, 0x0a, 0x0a, 0x0a, 0x01, 0x62, 0x6a, + 0x05, 0x0a, 0x03, 0x41, 0x2e, 0x42, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, + 0x2f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, + 0x09, 0x9a, 0x4a, 0x06, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x3a, 0x6d, 0x9a, 0x4a, 0x6a, 0x0a, 0x3c, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x35, 0x0a, 0x18, + 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2f, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x04, + 0x24, 0x2e, 0x69, 0x64, 0x1a, 0x03, 0x31, 0x30, 0x73, 0x22, 0x08, 0x0a, 0x06, 0x0a, 0x02, 0x32, + 0x73, 0x10, 0x03, 0x0a, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x5a, 0x08, 0x72, + 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x0a, 0x16, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x6a, + 0x0e, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x06, 0x1a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x22, + 0xc8, 0x04, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x05, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x66, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x0a, + 0x06, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, + 0x41, 0x74, 0x74, 0x72, 0x41, 0x48, 0x00, 0x52, 0x05, 0x61, 0x74, 0x74, 0x72, 0x41, 0x12, 0x26, + 0x0a, 0x01, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, + 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x50, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x2f, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x72, + 0x41, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x66, 0x6f, 0x6f, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x41, 0x1a, 0x2f, 0x0a, 0x05, 0x41, 0x74, 0x74, + 0x72, 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x03, 0x62, 0x61, 0x72, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x42, 0x3a, 0xa5, 0x01, 0x9a, 0x4a, 0xa1, + 0x01, 0x0a, 0x8a, 0x01, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x82, 0x01, 0x0a, 0x18, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0f, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x09, 0x24, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x27, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, + 0x79, 0x70, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x27, 0x49, 0x54, 0x45, 0x4d, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x27, 0x29, 0x1a, 0x03, 0x32, 0x30, 0x73, 0x22, 0x1f, 0x12, + 0x1d, 0x0a, 0x02, 0x31, 0x73, 0x11, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x3f, 0x19, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0xfb, 0x3f, 0x22, 0x03, 0x33, 0x30, 0x73, 0x28, 0x03, 0x0a, 0x12, + 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x5a, 0x08, 0x72, 0x65, 0x73, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x8d, 0x05, 0x0a, 0x04, 0x49, + 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x35, 0x0a, 0x08, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, + 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x1a, 0xf1, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, 0x12, 0x38, 0x0a, 0x06, + 0x61, 0x64, 0x64, 0x72, 0x5f, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x66, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x41, 0x48, 0x00, 0x52, + 0x05, 0x61, 0x64, 0x64, 0x72, 0x41, 0x12, 0x2f, 0x0a, 0x01, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, + 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x41, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, - 0x6f, 0x6f, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x41, 0x1a, 0x2f, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x72, - 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, - 0x62, 0x61, 0x72, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x42, 0x3a, 0xa5, 0x01, 0x9a, 0x4a, 0xa1, 0x01, - 0x0a, 0x8a, 0x01, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x82, 0x01, 0x0a, 0x18, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x47, 0x65, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0f, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x09, 0x24, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x27, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, - 0x70, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x27, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x31, 0x27, 0x29, 0x1a, 0x03, 0x32, 0x30, 0x73, 0x22, 0x1f, 0x12, 0x1d, - 0x0a, 0x02, 0x31, 0x73, 0x11, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x3f, 0x19, 0x33, 0x33, - 0x33, 0x33, 0x33, 0x33, 0xfb, 0x3f, 0x22, 0x03, 0x33, 0x30, 0x73, 0x28, 0x03, 0x0a, 0x12, 0x0a, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x5a, 0x08, 0x72, 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x8d, 0x05, 0x0a, 0x04, 0x49, 0x74, - 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x1a, 0xf1, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x61, 0x64, 0x64, 0x72, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, 0x12, 0x38, 0x0a, 0x06, 0x61, - 0x64, 0x64, 0x72, 0x5f, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x66, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x41, 0x48, 0x00, 0x52, 0x05, - 0x61, 0x64, 0x64, 0x72, 0x41, 0x12, 0x2f, 0x0a, 0x01, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, + 0x6f, 0x6f, 0x3a, 0x1d, 0x9a, 0x4a, 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, - 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x41, 0x12, - 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x6f, - 0x6f, 0x3a, 0x1d, 0x9a, 0x4a, 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, - 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x41, - 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x1d, 0x9a, 0x4a, 0x1a, - 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x22, 0x38, 0x0a, 0x0c, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x30, 0x10, 0x00, 0x12, - 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x31, 0x10, 0x01, 0x3a, 0x17, 0x9a, 0x4a, 0x14, 0x1a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, 0x0a, - 0x05, 0x61, 0x64, 0x64, 0x72, 0x33, 0x22, 0x71, 0x0a, 0x08, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, - 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, - 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x32, 0x10, 0x02, 0x12, - 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x33, 0x10, 0x03, - 0x1a, 0x17, 0x9a, 0x4a, 0x14, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, - 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x0e, 0x9a, 0x4a, 0x0b, 0x1a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x32, 0x5e, 0x0a, 0x11, 0x46, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, - 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x66, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x1a, 0x03, 0x9a, 0x4a, 0x00, 0x42, 0xad, 0x01, 0x9a, 0x4a, 0x22, 0x12, - 0x0f, 0x70, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x0f, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x1d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x66, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x46, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x0a, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x16, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x46, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x41, 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x1d, 0x9a, 0x4a, + 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x22, 0x38, 0x0a, 0x0c, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x4c, + 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x30, 0x10, 0x00, + 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x31, 0x10, 0x01, 0x3a, 0x17, 0x9a, 0x4a, 0x14, 0x1a, 0x12, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, + 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x33, 0x22, 0x71, 0x0a, 0x08, 0x49, 0x74, 0x65, 0x6d, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, + 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, + 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x32, 0x10, 0x02, + 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x33, 0x10, + 0x03, 0x1a, 0x17, 0x9a, 0x4a, 0x14, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, + 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x0e, 0x9a, 0x4a, 0x0b, 0x1a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x32, 0x5e, 0x0a, 0x11, 0x46, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x44, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x66, 0x65, 0x64, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x1a, 0x03, 0x9a, 0x4a, 0x00, 0x42, 0xad, 0x01, 0x9a, 0x4a, 0x22, + 0x12, 0x0f, 0x70, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x0f, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x1d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x66, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x46, 0x65, 0x64, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x0a, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x16, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, + 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/_examples/02_simple/federation/federation_grpc_federation.pb.go b/_examples/02_simple/federation/federation_grpc_federation.pb.go index 3fa18222..b387f1fd 100644 --- a/_examples/02_simple/federation/federation_grpc_federation.pb.go +++ b/_examples/02_simple/federation/federation_grpc_federation.pb.go @@ -59,6 +59,7 @@ type FederationService_Federation_GetPostResponseArgument struct { SortedItems []*user.Item SortedValues []int64 StringsJoin string + Url *grpcfedcel.URL Uuid *grpcfedcel.UUID Value1 string } @@ -666,7 +667,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte type localValueType struct { *grpcfed.LocalValue vars struct { - _def14 bool + _def15 bool a *A date *grpcfedcel.Time fixed_rand *grpcfedcel.Rand @@ -679,6 +680,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte sorted_items []*user.Item sorted_values []int64 strings_join string + url *grpcfedcel.URL uuid *grpcfedcel.UUID value1 string } @@ -687,7 +689,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte // A tree view of message dependencies is shown below. /* post ─┐ - _def14 ─┐ + _def15 ─┐ a ─┤ loc ─┐ │ jp_time ─┤ @@ -696,6 +698,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte sorted_items ─┤ sorted_values ─┤ strings_join ─┤ + url ─┤ date ─┐ │ rand_source ─┐ │ fixed_rand ─┐ │ @@ -751,15 +754,15 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte // This section's codes are generated by the following proto definition. /* def { - name: "_def14" + name: "_def15" by: "grpc.federation.log.info('output federation log', {'post_message': post})" } */ if err := grpcfed.EvalDef(ctx1, value, grpcfed.Def[bool, *localValueType]{ - Name: `_def14`, + Name: `_def15`, Type: grpcfed.CELBoolType, Setter: func(value *localValueType, v bool) error { - value.vars._def14 = v + value.vars._def15 = v return nil }, By: `grpc.federation.log.info('output federation log', {'post_message': post})`, @@ -975,6 +978,31 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte return nil, nil }) + grpcfed.GoWithRecover(eg, func() (any, error) { + + // This section's codes are generated by the following proto definition. + /* + def { + name: "url" + by: "grpc.federation.url.parse('https://test_user:password@example.com/path')" + } + */ + if err := grpcfed.EvalDef(ctx1, value, grpcfed.Def[*grpcfedcel.URL, *localValueType]{ + Name: `url`, + Type: grpcfed.CELObjectType("grpc.federation.url.URL"), + Setter: func(value *localValueType, v *grpcfedcel.URL) error { + value.vars.url = v + return nil + }, + By: `grpc.federation.url.parse('https://test_user:password@example.com/path')`, + ByCacheIndex: 21, + }); err != nil { + grpcfed.RecordErrorToSpan(ctx1, err) + return nil, err + } + return nil, nil + }) + grpcfed.GoWithRecover(eg, func() (any, error) { // This section's codes are generated by the following proto definition. @@ -992,7 +1020,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte return nil }, By: `grpc.federation.time.date(2023, 12, 25, 12, 10, 5, 0, grpc.federation.time.UTC())`, - ByCacheIndex: 21, + ByCacheIndex: 22, }); err != nil { grpcfed.RecordErrorToSpan(ctx1, err) return nil, err @@ -1013,7 +1041,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte return nil }, By: `grpc.federation.rand.newSource(date.unix())`, - ByCacheIndex: 22, + ByCacheIndex: 23, }); err != nil { grpcfed.RecordErrorToSpan(ctx1, err) return nil, err @@ -1034,7 +1062,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte return nil }, By: `grpc.federation.rand.new(rand_source)`, - ByCacheIndex: 23, + ByCacheIndex: 24, }); err != nil { grpcfed.RecordErrorToSpan(ctx1, err) return nil, err @@ -1055,7 +1083,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte return nil }, By: `.grpc.federation.uuid.newRandomFromRand(fixed_rand)`, - ByCacheIndex: 24, + ByCacheIndex: 25, }); err != nil { grpcfed.RecordErrorToSpan(ctx1, err) return nil, err @@ -1080,7 +1108,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte return nil }, By: `grpc.federation.metadata.incoming()['key1'][0]`, - ByCacheIndex: 25, + ByCacheIndex: 26, }); err != nil { grpcfed.RecordErrorToSpan(ctx1, err) return nil, err @@ -1105,6 +1133,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte req.SortedItems = value.vars.sorted_items req.SortedValues = value.vars.sorted_values req.StringsJoin = value.vars.strings_join + req.Url = value.vars.url req.Uuid = value.vars.uuid req.Value1 = value.vars.value1 @@ -1116,7 +1145,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*Post]{ Value: value, Expr: `post`, - CacheIndex: 26, + CacheIndex: 27, Setter: func(v *Post) error { ret.Post = v return nil @@ -1129,7 +1158,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `'hello'`, - CacheIndex: 27, + CacheIndex: 28, Setter: func(v string) error { ret.Str = v return nil @@ -1142,7 +1171,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `uuid.string()`, - CacheIndex: 28, + CacheIndex: 29, Setter: func(v string) error { ret.Uuid = v return nil @@ -1155,7 +1184,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `loc.string()`, - CacheIndex: 29, + CacheIndex: 30, Setter: func(v string) error { ret.Loc = v return nil @@ -1168,7 +1197,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `value1`, - CacheIndex: 30, + CacheIndex: 31, Setter: func(v string) error { ret.Value1 = v return nil @@ -1181,7 +1210,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `Item.ItemType.name(Item.ItemType.ITEM_TYPE_1)`, - CacheIndex: 31, + CacheIndex: 32, Setter: func(v string) error { ret.ItemTypeName = v return nil @@ -1194,7 +1223,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `Item.Location.LocationType.name(Item.Location.LocationType.LOCATION_TYPE_1)`, - CacheIndex: 32, + CacheIndex: 33, Setter: func(v string) error { ret.LocationTypeName = v return nil @@ -1207,7 +1236,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `user.Item.ItemType.name(user.Item.ItemType.ITEM_TYPE_2)`, - CacheIndex: 33, + CacheIndex: 34, Setter: func(v string) error { ret.UserItemTypeName = v return nil @@ -1220,7 +1249,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[user.Item_ItemType]{ Value: value, Expr: `user.Item.ItemType.value('ITEM_TYPE_1')`, - CacheIndex: 34, + CacheIndex: 35, Setter: func(v user.Item_ItemType) error { itemTypeValueEnumValue, err := s.cast_User_Item_ItemType__to__Federation_Item_ItemType(v) if err != nil { @@ -1237,7 +1266,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[user.Item_ItemType]{ Value: value, Expr: `user.Item.ItemType.value('ITEM_TYPE_1')`, - CacheIndex: 35, + CacheIndex: 36, Setter: func(v user.Item_ItemType) error { itemTypeValueIntValue, err := s.cast_User_Item_ItemType__to__int32(v) if err != nil { @@ -1254,7 +1283,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[Item_ItemType]{ Value: value, Expr: `1`, - CacheIndex: 36, + CacheIndex: 37, Setter: func(v Item_ItemType) error { ret.ItemTypeValueCast = v return nil @@ -1267,7 +1296,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[Item_Location_LocationType]{ Value: value, Expr: `Item.Location.LocationType.value('LOCATION_TYPE_1')`, - CacheIndex: 37, + CacheIndex: 38, Setter: func(v Item_Location_LocationType) error { locationTypeValueValue, err := s.cast_Federation_Item_Location_LocationType__to__int32(v) if err != nil { @@ -1284,7 +1313,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[user.Item_ItemType]{ Value: value, Expr: `user.Item.ItemType.value('ITEM_TYPE_2')`, - CacheIndex: 38, + CacheIndex: 39, Setter: func(v user.Item_ItemType) error { userItemTypeValueValue, err := s.cast_User_Item_ItemType__to__int32(v) if err != nil { @@ -1301,7 +1330,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*A]{ Value: value, Expr: `a`, - CacheIndex: 39, + CacheIndex: 40, Setter: func(v *A) error { ret.A = v return nil @@ -1314,7 +1343,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[[]int32]{ Value: value, Expr: `sorted_values`, - CacheIndex: 40, + CacheIndex: 41, Setter: func(v []int32) error { ret.SortedValues = v return nil @@ -1327,7 +1356,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[[]*user.Item]{ Value: value, Expr: `sorted_items`, - CacheIndex: 41, + CacheIndex: 42, Setter: func(v []*user.Item) error { sortedItemsValue, err := s.cast_repeated_User_Item__to__repeated_Federation_Item(v) if err != nil { @@ -1344,7 +1373,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[map[int64]string]{ Value: value, Expr: `map_value`, - CacheIndex: 42, + CacheIndex: 43, Setter: func(v map[int64]string) error { mapValueValue, err := s.cast_map_int64_string__to__map_int32_string(v) if err != nil { @@ -1361,7 +1390,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.DoubleValue]{ Value: value, Expr: `google.protobuf.DoubleValue{value: 1.23}`, - CacheIndex: 43, + CacheIndex: 44, Setter: func(v *wrapperspb.DoubleValue) error { doubleWrapperValueValue, err := s.cast_Google_Protobuf_DoubleValue__to__Google_Protobuf_DoubleValue(v) if err != nil { @@ -1378,7 +1407,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.DoubleValue]{ Value: value, Expr: `google.protobuf.FloatValue{value: 3.45}`, - CacheIndex: 44, + CacheIndex: 45, Setter: func(v *wrapperspb.DoubleValue) error { floatWrapperValueValue, err := s.cast_Google_Protobuf_DoubleValue__to__Google_Protobuf_FloatValue(v) if err != nil { @@ -1395,7 +1424,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.Int64Value]{ Value: value, Expr: `google.protobuf.Int64Value{value: 1}`, - CacheIndex: 45, + CacheIndex: 46, Setter: func(v *wrapperspb.Int64Value) error { i64WrapperValueValue, err := s.cast_Google_Protobuf_Int64Value__to__Google_Protobuf_Int64Value(v) if err != nil { @@ -1412,7 +1441,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.UInt64Value]{ Value: value, Expr: `google.protobuf.UInt64Value{value: uint(2)}`, - CacheIndex: 46, + CacheIndex: 47, Setter: func(v *wrapperspb.UInt64Value) error { u64WrapperValueValue, err := s.cast_Google_Protobuf_UInt64Value__to__Google_Protobuf_UInt64Value(v) if err != nil { @@ -1429,7 +1458,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.Int64Value]{ Value: value, Expr: `google.protobuf.Int32Value{value: 3}`, - CacheIndex: 47, + CacheIndex: 48, Setter: func(v *wrapperspb.Int64Value) error { i32WrapperValueValue, err := s.cast_Google_Protobuf_Int64Value__to__Google_Protobuf_Int32Value(v) if err != nil { @@ -1446,7 +1475,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.UInt64Value]{ Value: value, Expr: `google.protobuf.UInt32Value{value: uint(4)}`, - CacheIndex: 48, + CacheIndex: 49, Setter: func(v *wrapperspb.UInt64Value) error { u32WrapperValueValue, err := s.cast_Google_Protobuf_UInt64Value__to__Google_Protobuf_UInt32Value(v) if err != nil { @@ -1463,7 +1492,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.BoolValue]{ Value: value, Expr: `google.protobuf.BoolValue{value: true}`, - CacheIndex: 49, + CacheIndex: 50, Setter: func(v *wrapperspb.BoolValue) error { boolWrapperValueValue, err := s.cast_Google_Protobuf_BoolValue__to__Google_Protobuf_BoolValue(v) if err != nil { @@ -1480,7 +1509,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.StringValue]{ Value: value, Expr: `google.protobuf.StringValue{value: 'hello'}`, - CacheIndex: 50, + CacheIndex: 51, Setter: func(v *wrapperspb.StringValue) error { stringWrapperValueValue, err := s.cast_Google_Protobuf_StringValue__to__Google_Protobuf_StringValue(v) if err != nil { @@ -1497,7 +1526,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*wrapperspb.BytesValue]{ Value: value, Expr: `google.protobuf.BytesValue{value: bytes('world')}`, - CacheIndex: 51, + CacheIndex: 52, Setter: func(v *wrapperspb.BytesValue) error { bytesWrapperValueValue, err := s.cast_Google_Protobuf_BytesValue__to__Google_Protobuf_BytesValue(v) if err != nil { @@ -1514,7 +1543,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `'hello\nworld'`, - CacheIndex: 52, + CacheIndex: 53, Setter: func(v string) error { ret.Hello = v return nil @@ -1527,7 +1556,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*timestamppb.Timestamp]{ Value: value, Expr: `null`, - CacheIndex: 53, + CacheIndex: 54, Setter: func(v *timestamppb.Timestamp) error { ret.NullTimestamp = v return nil @@ -1540,7 +1569,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*timestamppb.Timestamp]{ Value: value, Expr: `null_value`, - CacheIndex: 54, + CacheIndex: 55, Setter: func(v *timestamppb.Timestamp) error { ret.NullTimestamp2 = v return nil @@ -1553,7 +1582,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*timestamppb.Timestamp]{ Value: value, Expr: `true ? null : google.protobuf.Timestamp{}`, - CacheIndex: 55, + CacheIndex: 56, Setter: func(v *timestamppb.Timestamp) error { ret.NullTimestamp3 = v return nil @@ -1566,7 +1595,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `jp_time.location().string()`, - CacheIndex: 56, + CacheIndex: 57, Setter: func(v string) error { ret.JpLoc = v return nil @@ -1579,7 +1608,7 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `strings_join`, - CacheIndex: 57, + CacheIndex: 58, Setter: func(v string) error { ret.StringsJoin = v return nil @@ -1588,6 +1617,19 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte grpcfed.RecordErrorToSpan(ctx, err) return nil, err } + // (grpc.federation.field).by = "url.user().username()" + if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ + Value: value, + Expr: `url.user().username()`, + CacheIndex: 59, + Setter: func(v string) error { + ret.UrlUserName = v + return nil + }, + }); err != nil { + grpcfed.RecordErrorToSpan(ctx, err) + return nil, err + } grpcfed.Logger(ctx).DebugContext(ctx, "resolved federation.GetPostResponse", slog.Any("federation.GetPostResponse", s.logvalue_Federation_GetPostResponse(ret))) return ret, nil @@ -1633,7 +1675,7 @@ func (s *FederationService) resolve_Federation_Post(ctx context.Context, req *Fe if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `$.id`, - CacheIndex: 58, + CacheIndex: 60, Setter: func(v string) error { args.Id = v return nil @@ -1649,7 +1691,7 @@ func (s *FederationService) resolve_Federation_Post(ctx context.Context, req *Fe return grpcfed.WithRetry(ctx, &grpcfed.RetryParam[post.GetPostResponse]{ Value: value, If: `true`, - CacheIndex: 59, + CacheIndex: 61, BackOff: b, Body: func() (*post.GetPostResponse, error) { return s.client.Post_PostServiceClient.GetPost(ctx, args) @@ -1684,7 +1726,7 @@ func (s *FederationService) resolve_Federation_Post(ctx context.Context, req *Fe return nil }, By: `res.post`, - ByCacheIndex: 60, + ByCacheIndex: 62, }); err != nil { grpcfed.RecordErrorToSpan(ctx, err) return nil, err @@ -1713,7 +1755,7 @@ func (s *FederationService) resolve_Federation_Post(ctx context.Context, req *Fe if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*post.Post]{ Value: value, Expr: `post`, - CacheIndex: 61, + CacheIndex: 63, Setter: func(v *post.Post) error { args.Id = v.GetId() args.Title = v.GetTitle() @@ -1751,7 +1793,7 @@ func (s *FederationService) resolve_Federation_Post(ctx context.Context, req *Fe if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[*User]{ Value: value, Expr: `user`, - CacheIndex: 62, + CacheIndex: 64, Setter: func(v *User) error { ret.User = v return nil @@ -1807,7 +1849,7 @@ func (s *FederationService) resolve_Federation_User(ctx context.Context, req *Fe if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, Expr: `$.user_id`, - CacheIndex: 63, + CacheIndex: 65, Setter: func(v string) error { args.Id = v return nil @@ -1819,7 +1861,7 @@ func (s *FederationService) resolve_Federation_User(ctx context.Context, req *Fe if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[user.Item_ItemType]{ Value: value, Expr: `user.Item.ItemType.value('ITEM_TYPE_1')`, - CacheIndex: 64, + CacheIndex: 66, Setter: func(v user.Item_ItemType) error { typeValue, err := s.cast_User_Item_ItemType__to__int32(v) if err != nil { @@ -1845,7 +1887,7 @@ func (s *FederationService) resolve_Federation_User(ctx context.Context, req *Fe return grpcfed.WithRetry(ctx, &grpcfed.RetryParam[user.GetUserResponse]{ Value: value, If: `true`, - CacheIndex: 65, + CacheIndex: 67, BackOff: b, Body: func() (*user.GetUserResponse, error) { return s.client.User_UserServiceClient.GetUser(ctx, args) @@ -1880,7 +1922,7 @@ func (s *FederationService) resolve_Federation_User(ctx context.Context, req *Fe return nil }, By: `res.user`, - ByCacheIndex: 66, + ByCacheIndex: 68, }); err != nil { grpcfed.RecordErrorToSpan(ctx, err) return nil, err @@ -2386,6 +2428,7 @@ func (s *FederationService) logvalue_Federation_GetPostResponse(v *GetPostRespon slog.Any("null_timestamp3", s.logvalue_Google_Protobuf_Timestamp(v.GetNullTimestamp3())), slog.String("jp_loc", v.GetJpLoc()), slog.String("strings_join", v.GetStringsJoin()), + slog.String("url_user_name", v.GetUrlUserName()), ) } diff --git a/_examples/02_simple/main_test.go b/_examples/02_simple/main_test.go index 05c702e4..070bcd26 100644 --- a/_examples/02_simple/main_test.go +++ b/_examples/02_simple/main_test.go @@ -205,6 +205,7 @@ func TestFederation(t *testing.T) { if err != nil { t.Fatal(err) } + if diff := cmp.Diff(res, &federation.GetPostResponse{ Post: &federation.Post{ Id: "foo", @@ -317,6 +318,7 @@ func TestFederation(t *testing.T) { NullTimestamp3: nil, JpLoc: "JST", StringsJoin: "a,b,c", + UrlUserName: "test_user", }, cmpopts.IgnoreUnexported( federation.GetPostResponse{}, federation.Post{}, diff --git a/_examples/02_simple/proto/federation/federation.proto b/_examples/02_simple/proto/federation/federation.proto index d22b788d..98ab0fb3 100644 --- a/_examples/02_simple/proto/federation/federation.proto +++ b/_examples/02_simple/proto/federation/federation.proto @@ -32,6 +32,7 @@ message GetPostResponse { } } def { name: "strings_join" by: "grpc.federation.strings.join(['a', 'b', 'c'], ',')" } + def { name: "url" by: "grpc.federation.url.parse('https://test_user:password@example.com/path')" } def { name: "date" by: "grpc.federation.time.date(2023, 12, 25, 12, 10, 5, 0, grpc.federation.time.UTC())" } def { name: "rand_source" by: "grpc.federation.rand.newSource(date.unix())" } def { name: "fixed_rand" by: "grpc.federation.rand.new(rand_source)" } @@ -78,6 +79,7 @@ message GetPostResponse { google.protobuf.Timestamp null_timestamp3 = 30 [(grpc.federation.field).by = "true ? null : google.protobuf.Timestamp{}"]; string jp_loc = 31 [(grpc.federation.field).by = "jp_time.location().string()"]; string strings_join = 32 [(grpc.federation.field).by = "strings_join"]; + string url_user_name = 33 [(grpc.federation.field).by = "url.user().username()"]; } message A { diff --git a/grpc/federation/cel/lib.go b/grpc/federation/cel/lib.go index 24f55c10..8d42c833 100644 --- a/grpc/federation/cel/lib.go +++ b/grpc/federation/cel/lib.go @@ -18,6 +18,7 @@ func NewLibrary(typeAdapter types.Adapter) *Library { return &Library{ name: "grpc.federation.static", subLibs: []cel.SingletonLibrary{ + NewURLLibrary(typeAdapter), NewStringsLibrary(), NewTimeLibrary(typeAdapter), NewListLibrary(typeAdapter), diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go new file mode 100644 index 00000000..cd6bc517 --- /dev/null +++ b/grpc/federation/cel/url.go @@ -0,0 +1,292 @@ +package cel + +import ( + "context" + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "net/url" +) + +const URLPackageName = "url" + +var ( + URLType = cel.ObjectType("grpc.federation.url.URL") + UserinfoType = cel.ObjectType("grpc.federation.url.Userinfo") +) + +func (x *URL) GoURL() (url.URL, error) { + user, err := x.GetUser().GoUserinfo() + if err != nil { + return url.URL{}, err + } + + return url.URL{ + Scheme: x.GetScheme(), + Opaque: x.GetOpaque(), + User: user, + Host: x.GetHost(), + Path: x.GetPath(), + RawPath: x.GetRawPath(), + ForceQuery: x.GetForceQuery(), + RawQuery: x.GetRawQuery(), + Fragment: x.GetFragment(), + }, nil +} + +func (x *Userinfo) GoUserinfo() (*url.Userinfo, error) { + if x.GetPasswordSet() { + return url.UserPassword(x.GetUsername(), x.GetPassword()), nil + } else { + return url.User(x.GetUsername()), nil + } +} + +var _ cel.SingletonLibrary = new(URLLibrary) + +type URLLibrary struct { + typeAdapter types.Adapter +} + +func NewURLLibrary(typeAdapter types.Adapter) *URLLibrary { + return &URLLibrary{ + typeAdapter: typeAdapter, + } +} + +func (lib *URLLibrary) LibraryName() string { + return packageName(URLPackageName) +} + +func createURLName(name string) string { + return createName(URLPackageName, name) +} + +func createURLID(name string) string { + return createID(URLPackageName, name) +} + +func (lib *URLLibrary) refToGoURLValue(v ref.Val) (url.URL, error) { + return v.Value().(*URL).GoURL() +} + +func (lib *URLLibrary) toURLValue(v url.URL) ref.Val { + userinfo := &Userinfo{} + if v.User != nil { + password, hasPassword := v.User.Password() + userinfo = &Userinfo{ + Username: v.User.Username(), + Password: password, + PasswordSet: hasPassword, + } + } + + return lib.typeAdapter.NativeToValue(&URL{ + Scheme: v.Scheme, + Opaque: v.Opaque, + User: userinfo, + Host: v.Host, + Path: v.Path, + RawPath: v.RawPath, + ForceQuery: v.ForceQuery, + RawQuery: v.RawQuery, + Fragment: v.Fragment, + }) +} + +func (lib *URLLibrary) toUserinfoValue(username, password string, passwordSet bool) ref.Val { + return lib.typeAdapter.NativeToValue(&Userinfo{Username: username, Password: password, PasswordSet: passwordSet}) +} + +func (lib *URLLibrary) CompileOptions() []cel.EnvOption { + opts := []cel.EnvOption{} + + for _, funcOpts := range [][]cel.EnvOption{ + // URL functions + BindFunction( + createURLName("parse"), + OverloadFunc(createURLID("parse_string_url"), []*cel.Type{cel.StringType}, URLType, + func(_ context.Context, args ...ref.Val) ref.Val { + v, err := url.Parse(string(args[0].(types.String))) + if err != nil { + return types.NewErr(err.Error()) + } + return lib.toURLValue(*v) + }, + ), + ), + BindMemberFunction( + "scheme", + MemberOverloadFunc(createTimeID("scheme_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := lib.refToGoURLValue(self) + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Scheme) + }, + ), + ), + BindMemberFunction( + "opaque", + MemberOverloadFunc(createTimeID("opaque_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Opaque) + }, + ), + ), + BindMemberFunction( + "user", + MemberOverloadFunc(createTimeID("user_url_userinfo"), URLType, []*cel.Type{}, UserinfoType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + password, hasPassword := v.User.Password() + return lib.toUserinfoValue(v.User.Username(), password, hasPassword) + }, + ), + ), + BindMemberFunction( + "host", + MemberOverloadFunc(createTimeID("host_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Host) + }, + ), + ), + BindMemberFunction( + "path", + MemberOverloadFunc(createTimeID("path_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Path) + }, + ), + ), + BindMemberFunction( + "rawPath", + MemberOverloadFunc(createTimeID("rawPath_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.RawPath) + }, + ), + ), + BindMemberFunction( + "forceQuery", + MemberOverloadFunc(createTimeID("forceQuery_url_bool"), URLType, []*cel.Type{}, cel.BoolType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.Bool(v.ForceQuery) + }, + ), + ), + BindMemberFunction( + "rawQuery", + MemberOverloadFunc(createTimeID("rawQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.RawQuery) + }, + ), + ), + BindMemberFunction( + "fragment", + MemberOverloadFunc(createTimeID("fragment_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Fragment) + }, + ), + ), + BindMemberFunction( + "rawFragment", + MemberOverloadFunc(createTimeID("rawFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.RawFragment) + }, + ), + ), + + // Userinfo functions + BindMemberFunction( + "username", + MemberOverloadFunc(createTimeID("username_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*Userinfo).GoUserinfo() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Username()) + }, + ), + ), + BindMemberFunction( + "password", + MemberOverloadFunc(createTimeID("password_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*Userinfo).GoUserinfo() + if err != nil { + return types.NewErr(err.Error()) + } + password, hasPassword := v.Password() + if hasPassword { + return types.String(password) + } else { + return types.String("") + } + }, + ), + ), + BindMemberFunction( + "passwordSet", + MemberOverloadFunc(createTimeID("passwordSet_userinfo_bool"), UserinfoType, []*cel.Type{}, cel.BoolType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*Userinfo).GoUserinfo() + if err != nil { + return types.NewErr(err.Error()) + } + _, hasPassword := v.Password() + return types.Bool(hasPassword) + }, + ), + ), + } { + opts = append(opts, funcOpts...) + } + + return opts +} + +func (lib *URLLibrary) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} diff --git a/grpc/federation/cel/url.pb.go b/grpc/federation/cel/url.pb.go new file mode 100644 index 00000000..4b9a1c17 --- /dev/null +++ b/grpc/federation/cel/url.pb.go @@ -0,0 +1,330 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc (unknown) +// source: grpc/federation/url.proto + +package cel + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// URL represents the structure of the URL in net/url package. +type URL struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"` + Opaque string `protobuf:"bytes,2,opt,name=opaque,proto3" json:"opaque,omitempty"` + User *Userinfo `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + Host string `protobuf:"bytes,4,opt,name=host,proto3" json:"host,omitempty"` + Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + RawPath string `protobuf:"bytes,6,opt,name=raw_path,json=rawPath,proto3" json:"raw_path,omitempty"` + OmitHost bool `protobuf:"varint,7,opt,name=omit_host,json=omitHost,proto3" json:"omit_host,omitempty"` + ForceQuery bool `protobuf:"varint,8,opt,name=force_query,json=forceQuery,proto3" json:"force_query,omitempty"` + RawQuery string `protobuf:"bytes,9,opt,name=raw_query,json=rawQuery,proto3" json:"raw_query,omitempty"` + Fragment string `protobuf:"bytes,10,opt,name=fragment,proto3" json:"fragment,omitempty"` + RawFragment string `protobuf:"bytes,11,opt,name=raw_fragment,json=rawFragment,proto3" json:"raw_fragment,omitempty"` +} + +func (x *URL) Reset() { + *x = URL{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_federation_url_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *URL) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*URL) ProtoMessage() {} + +func (x *URL) ProtoReflect() protoreflect.Message { + mi := &file_grpc_federation_url_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use URL.ProtoReflect.Descriptor instead. +func (*URL) Descriptor() ([]byte, []int) { + return file_grpc_federation_url_proto_rawDescGZIP(), []int{0} +} + +func (x *URL) GetScheme() string { + if x != nil { + return x.Scheme + } + return "" +} + +func (x *URL) GetOpaque() string { + if x != nil { + return x.Opaque + } + return "" +} + +func (x *URL) GetUser() *Userinfo { + if x != nil { + return x.User + } + return nil +} + +func (x *URL) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *URL) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *URL) GetRawPath() string { + if x != nil { + return x.RawPath + } + return "" +} + +func (x *URL) GetOmitHost() bool { + if x != nil { + return x.OmitHost + } + return false +} + +func (x *URL) GetForceQuery() bool { + if x != nil { + return x.ForceQuery + } + return false +} + +func (x *URL) GetRawQuery() string { + if x != nil { + return x.RawQuery + } + return "" +} + +func (x *URL) GetFragment() string { + if x != nil { + return x.Fragment + } + return "" +} + +func (x *URL) GetRawFragment() string { + if x != nil { + return x.RawFragment + } + return "" +} + +// Userinfo represents username and password information. +type Userinfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + PasswordSet bool `protobuf:"varint,3,opt,name=password_set,json=passwordSet,proto3" json:"password_set,omitempty"` +} + +func (x *Userinfo) Reset() { + *x = Userinfo{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_federation_url_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Userinfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Userinfo) ProtoMessage() {} + +func (x *Userinfo) ProtoReflect() protoreflect.Message { + mi := &file_grpc_federation_url_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Userinfo.ProtoReflect.Descriptor instead. +func (*Userinfo) Descriptor() ([]byte, []int) { + return file_grpc_federation_url_proto_rawDescGZIP(), []int{1} +} + +func (x *Userinfo) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *Userinfo) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *Userinfo) GetPasswordSet() bool { + if x != nil { + return x.PasswordSet + } + return false +} + +var File_grpc_federation_url_proto protoreflect.FileDescriptor + +var file_grpc_federation_url_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x75, 0x72, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x75, 0x72, 0x6c, + 0x22, 0xc5, 0x02, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x75, 0x72, 0x6c, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, + 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x61, 0x77, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1b, + 0x0a, 0x09, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x6f, 0x6d, 0x69, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, + 0x72, 0x61, 0x77, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x72, 0x61, 0x77, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x61, 0x77, + 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x65, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, + 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x65, 0x74, 0x42, + 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x65, + 0x72, 0x63, 0x61, 0x72, 0x69, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x66, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x65, 0x6c, 0x3b, 0x63, 0x65, 0x6c, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_grpc_federation_url_proto_rawDescOnce sync.Once + file_grpc_federation_url_proto_rawDescData = file_grpc_federation_url_proto_rawDesc +) + +func file_grpc_federation_url_proto_rawDescGZIP() []byte { + file_grpc_federation_url_proto_rawDescOnce.Do(func() { + file_grpc_federation_url_proto_rawDescData = protoimpl.X.CompressGZIP(file_grpc_federation_url_proto_rawDescData) + }) + return file_grpc_federation_url_proto_rawDescData +} + +var file_grpc_federation_url_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_grpc_federation_url_proto_goTypes = []interface{}{ + (*URL)(nil), // 0: grpc.federation.url.URL + (*Userinfo)(nil), // 1: grpc.federation.url.Userinfo +} +var file_grpc_federation_url_proto_depIdxs = []int32{ + 1, // 0: grpc.federation.url.URL.user:type_name -> grpc.federation.url.Userinfo + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_grpc_federation_url_proto_init() } +func file_grpc_federation_url_proto_init() { + if File_grpc_federation_url_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_grpc_federation_url_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*URL); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_federation_url_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Userinfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_grpc_federation_url_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_grpc_federation_url_proto_goTypes, + DependencyIndexes: file_grpc_federation_url_proto_depIdxs, + MessageInfos: file_grpc_federation_url_proto_msgTypes, + }.Build() + File_grpc_federation_url_proto = out.File + file_grpc_federation_url_proto_rawDesc = nil + file_grpc_federation_url_proto_goTypes = nil + file_grpc_federation_url_proto_depIdxs = nil +} diff --git a/grpc/federation/cel/url_test.go b/grpc/federation/cel/url_test.go new file mode 100644 index 00000000..8ebcbd23 --- /dev/null +++ b/grpc/federation/cel/url_test.go @@ -0,0 +1,82 @@ +package cel_test + +import ( + "context" + "fmt" + "net/url" + "testing" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + cellib "github.com/mercari/grpc-federation/grpc/federation/cel" +) + +func TestParseURL(t *testing.T) { + tests := []struct { + name string + expr string + args map[string]any + cmp func(ref.Val) error + }{ + { + name: "parse", + expr: "grpc.federation.url.parse('https://example.com/path?query=1#fragment')", + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.URL) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotURL, err := gotV.GoURL() + if err != nil { + return err + } + expected, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + if diff := cmp.Diff(gotURL, expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + } + + reg, err := types.NewRegistry(new(cellib.URL), new(cellib.Userinfo)) + if err != nil { + t.Fatal(err) + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + env, err := cel.NewEnv( + cel.Variable(cellib.ContextVariableName, cel.ObjectType(cellib.ContextTypeName)), + cel.Lib(cellib.NewURLLibrary(reg)), + ) + if err != nil { + t.Fatal(err) + } + ast, iss := env.Compile(test.expr) + if iss.Err() != nil { + t.Fatal(iss.Err()) + } + program, err := env.Program(ast) + if err != nil { + t.Fatal(err) + } + args := map[string]any{cellib.ContextVariableName: cellib.NewContextValue(context.Background())} + for k, v := range test.args { + args[k] = v + } + out, _, err := program.Eval(args) + if err != nil { + t.Fatal(err) + } + if err := test.cmp(out); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/proto/grpc/federation/url.proto b/proto/grpc/federation/url.proto new file mode 100644 index 00000000..2b287195 --- /dev/null +++ b/proto/grpc/federation/url.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package grpc.federation.url; + +option go_package = "github.com/mercari/grpc-federation/grpc/federation/cel;cel"; + +// URL represents the structure of the URL in net/url package. +message URL { + string scheme = 1; + string opaque = 2; + Userinfo user = 3; + string host = 4; + string path = 5; + string raw_path = 6; + bool omit_host = 7; + bool force_query = 8; + string raw_query = 9; + string fragment = 10; + string raw_fragment = 11; +} + +// Userinfo represents username and password information. +message Userinfo { + string username = 1; + string password = 2; + bool password_set = 3; +} From ebbbf3d49c42967ea4da2dd1efa117120993a6f6 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Fri, 6 Sep 2024 20:44:20 +0900 Subject: [PATCH 02/12] =?UTF-8?q?=E2=9C=A8=20impl=20URL=20and=20Useinfo=20?= =?UTF-8?q?functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url.go | 235 +++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index cd6bc517..359086d3 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -5,6 +5,7 @@ import ( "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" "net/url" ) @@ -115,6 +116,18 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), + BindFunction( + createURLName("parseRequestURI"), + OverloadFunc(createURLID("parseRequestURI_string_url"), []*cel.Type{cel.StringType}, URLType, + func(_ context.Context, args ...ref.Val) ref.Val { + v, err := url.ParseRequestURI(string(args[0].(types.String))) + if err != nil { + return types.NewErr(err.Error()) + } + return lib.toURLValue(*v) + }, + ), + ), BindMemberFunction( "scheme", MemberOverloadFunc(createTimeID("scheme_url_string"), URLType, []*cel.Type{}, cel.StringType, @@ -236,8 +249,218 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), + BindMemberFunction( + "escapedFragment", + MemberOverloadFunc(createTimeID("escapedFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.EscapedFragment()) + }, + ), + ), + BindMemberFunction( + "escapedPath", + MemberOverloadFunc(createTimeID("escapedPath_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.EscapedPath()) + }, + ), + ), + BindMemberFunction( + "hostname", + MemberOverloadFunc(createTimeID("hostname_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Hostname()) + }, + ), + ), + BindMemberFunction( + "isAbs", + MemberOverloadFunc(createTimeID("isAbs_url_bool"), URLType, []*cel.Type{}, cel.BoolType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.Bool(v.IsAbs()) + }, + ), + ), + BindMemberFunction( + "joinPath", + MemberOverloadFunc(createTimeID("joinPath_url_strings_url"), URLType, []*cel.Type{cel.ListType(cel.StringType)}, URLType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + + elems := args[0].(traits.Lister) + var paths []string + for i := types.Int(0); i < elems.Size().(types.Int); i++ { + pathElem := elems.Get(i) + paths = append(paths, string(pathElem.(types.String))) + } + + v.Path, err = url.JoinPath(v.Path, paths...) + + return lib.toURLValue(v) + }, + ), + ), + BindMemberFunction( + "marshalBinary", + MemberOverloadFunc(createTimeID("MarshalBinary_url_bytes"), URLType, []*cel.Type{}, cel.BytesType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + + b, err := v.MarshalBinary() + if err != nil { + return types.NewErr(err.Error()) + } + + return types.Bytes(b) + }, + ), + ), + BindMemberFunction( + "parse", + MemberOverloadFunc(createTimeID("parse_url_string_url"), URLType, []*cel.Type{cel.StringType}, URLType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + + u, err := v.Parse(string(args[0].(types.String))) + if err != nil { + return types.NewErr(err.Error()) + } + + return lib.toURLValue(*u) + }, + ), + ), + BindMemberFunction( + "port", + MemberOverloadFunc(createTimeID("port_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Port()) + }, + ), + ), + BindMemberFunction( + "query", + MemberOverloadFunc(createURLID("query_url_map"), URLType, []*cel.Type{}, cel.MapType(cel.StringType, cel.ListType(cel.StringType)), + func(ctx context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + + adapter := types.DefaultTypeAdapter + queryParams := v.Query() + queryMap := map[ref.Val]ref.Val{} + for key, values := range queryParams { + var valueList []ref.Val + for _, val := range values { + valueList = append(valueList, types.String(val)) + } + queryMap[types.String(key)] = types.NewStringList(adapter, values) + } + + return types.NewRefValMap(adapter, queryMap) + }, + ), + ), + BindMemberFunction( + "requestURI", + MemberOverloadFunc(createTimeID("requestURI_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.RequestURI()) + }, + ), + ), + BindMemberFunction( + "resolveReference", + MemberOverloadFunc(createTimeID("resolveReference_url_url_url"), URLType, []*cel.Type{URLType}, URLType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + + r, err := args[0].Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + u := v.ResolveReference(&r) + + return lib.toURLValue(*u) + }, + ), + ), + BindMemberFunction( + "string", + MemberOverloadFunc(createTimeID("string_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + return types.String(self.Value().(*URL).String()) + }, + ), + ), + BindMemberFunction( + "unmarshalBinary", + MemberOverloadFunc(createTimeID("unmarshalBinary_url_bytes_url"), URLType, []*cel.Type{cel.BytesType}, URLType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + var u url.URL + err := u.UnmarshalBinary(args[0].(types.Bytes)) + if err != nil { + return types.NewErr(err.Error()) + } + return lib.toURLValue(u) + }, + ), + ), // Userinfo functions + BindFunction( + createURLName("user"), + OverloadFunc(createURLID("user_string_userinfo"), []*cel.Type{cel.StringType}, UserinfoType, + func(_ context.Context, args ...ref.Val) ref.Val { + return lib.toUserinfoValue(string(args[0].(types.String)), "", false) + }, + ), + ), + BindFunction( + createURLName("userPassword"), + OverloadFunc(createURLID("userPassword_string_string_userinfo"), []*cel.Type{cel.StringType, cel.StringType}, UserinfoType, + func(_ context.Context, args ...ref.Val) ref.Val { + return lib.toUserinfoValue(string(args[0].(types.String)), string(args[1].(types.String)), true) + }, + ), + ), BindMemberFunction( "username", MemberOverloadFunc(createTimeID("username_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, @@ -280,6 +503,18 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), + BindMemberFunction( + "string", + MemberOverloadFunc(createTimeID("string_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*Userinfo).GoUserinfo() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.String()) + }, + ), + ), } { opts = append(opts, funcOpts...) } From 122a210b8261959ddcccef125a987a3943cd7dca Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Fri, 13 Sep 2024 16:27:29 +0900 Subject: [PATCH 03/12] =?UTF-8?q?=E2=9C=A8=20impl=20remaining=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url.go | 135 ++++++++++++++++++++++++++++--------- 1 file changed, 103 insertions(+), 32 deletions(-) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index 359086d3..40472105 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -17,9 +17,13 @@ var ( ) func (x *URL) GoURL() (url.URL, error) { - user, err := x.GetUser().GoUserinfo() - if err != nil { - return url.URL{}, err + var user *url.Userinfo + if u := x.GetUser(); u != nil { + if u2, err := u.GoUserinfo(); err != nil { + return url.URL{}, err + } else { + user = u2 + } } return url.URL{ @@ -72,7 +76,7 @@ func (lib *URLLibrary) refToGoURLValue(v ref.Val) (url.URL, error) { } func (lib *URLLibrary) toURLValue(v url.URL) ref.Val { - userinfo := &Userinfo{} + var userinfo *Userinfo if v.User != nil { password, hasPassword := v.User.Password() userinfo = &Userinfo{ @@ -103,6 +107,67 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { opts := []cel.EnvOption{} for _, funcOpts := range [][]cel.EnvOption{ + BindFunction( + createURLName("joinPath"), + OverloadFunc(createURLID("joinPath_string_strings_url"), []*cel.Type{cel.StringType, cel.ListType(cel.StringType)}, URLType, + func(_ context.Context, args ...ref.Val) ref.Val { + base := string(args[0].(types.String)) + elems := args[1].(traits.Lister) + var paths []string + for i := types.Int(0); i < elems.Size().(types.Int); i++ { + pathElem := elems.Get(i) + paths = append(paths, string(pathElem.(types.String))) + } + + result, err := url.JoinPath(base, paths...) + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(result) + }, + ), + ), + BindFunction( + createURLName("pathEscape"), + OverloadFunc(createURLID("pathEscape_string_string"), []*cel.Type{cel.StringType}, cel.StringType, + func(_ context.Context, args ...ref.Val) ref.Val { + return types.String(url.PathEscape(string(args[0].(types.String)))) + }, + ), + ), + BindFunction( + createURLName("pathUnescape"), + OverloadFunc(createURLID("pathUnescape_string_string"), []*cel.Type{cel.StringType}, cel.StringType, + func(_ context.Context, args ...ref.Val) ref.Val { + result, err := url.PathUnescape(string(args[0].(types.String))) + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(result) + }, + ), + ), + BindFunction( + createURLName("queryEscape"), + OverloadFunc(createURLID("queryEscape_string_string"), []*cel.Type{cel.StringType}, cel.StringType, + func(_ context.Context, args ...ref.Val) ref.Val { + return types.String(url.QueryEscape(string(args[0].(types.String)))) + }, + ), + ), + BindFunction( + createURLName("queryUnescape"), + OverloadFunc(createURLID("queryUnescape_string_string"), []*cel.Type{cel.StringType}, cel.StringType, + func(_ context.Context, args ...ref.Val) ref.Val { + result, err := url.QueryUnescape(string(args[0].(types.String))) + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(result) + }, + ), + ), + // URL functions BindFunction( createURLName("parse"), @@ -130,7 +195,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "scheme", - MemberOverloadFunc(createTimeID("scheme_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("scheme_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := lib.refToGoURLValue(self) if err != nil { @@ -142,7 +207,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "opaque", - MemberOverloadFunc(createTimeID("opaque_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("opaque_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -154,7 +219,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "user", - MemberOverloadFunc(createTimeID("user_url_userinfo"), URLType, []*cel.Type{}, UserinfoType, + MemberOverloadFunc(createURLID("user_url_userinfo"), URLType, []*cel.Type{}, UserinfoType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -167,7 +232,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "host", - MemberOverloadFunc(createTimeID("host_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("host_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -179,7 +244,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "path", - MemberOverloadFunc(createTimeID("path_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("path_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -191,7 +256,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "rawPath", - MemberOverloadFunc(createTimeID("rawPath_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("rawPath_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -201,21 +266,23 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), + // forceQuery is changed to return String BindMemberFunction( "forceQuery", - MemberOverloadFunc(createTimeID("forceQuery_url_bool"), URLType, []*cel.Type{}, cel.BoolType, + MemberOverloadFunc(createURLID("forceQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { return types.NewErr(err.Error()) } - return types.Bool(v.ForceQuery) + v.ForceQuery = true + return types.String(v.String()) }, ), ), BindMemberFunction( "rawQuery", - MemberOverloadFunc(createTimeID("rawQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("rawQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -227,7 +294,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "fragment", - MemberOverloadFunc(createTimeID("fragment_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("fragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -239,7 +306,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "rawFragment", - MemberOverloadFunc(createTimeID("rawFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("rawFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -251,7 +318,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "escapedFragment", - MemberOverloadFunc(createTimeID("escapedFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("escapedFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -263,7 +330,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "escapedPath", - MemberOverloadFunc(createTimeID("escapedPath_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("escapedPath_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -275,7 +342,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "hostname", - MemberOverloadFunc(createTimeID("hostname_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("hostname_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -287,7 +354,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "isAbs", - MemberOverloadFunc(createTimeID("isAbs_url_bool"), URLType, []*cel.Type{}, cel.BoolType, + MemberOverloadFunc(createURLID("isAbs_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -299,7 +366,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "joinPath", - MemberOverloadFunc(createTimeID("joinPath_url_strings_url"), URLType, []*cel.Type{cel.ListType(cel.StringType)}, URLType, + MemberOverloadFunc(createURLID("joinPath_url_strings_url"), URLType, []*cel.Type{cel.ListType(cel.StringType)}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -321,7 +388,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "marshalBinary", - MemberOverloadFunc(createTimeID("MarshalBinary_url_bytes"), URLType, []*cel.Type{}, cel.BytesType, + MemberOverloadFunc(createURLID("MarshalBinary_url_bytes"), URLType, []*cel.Type{}, cel.BytesType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -339,7 +406,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "parse", - MemberOverloadFunc(createTimeID("parse_url_string_url"), URLType, []*cel.Type{cel.StringType}, URLType, + MemberOverloadFunc(createURLID("parse_url_string_url"), URLType, []*cel.Type{cel.StringType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -357,7 +424,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "port", - MemberOverloadFunc(createTimeID("port_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("port_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -393,7 +460,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "requestURI", - MemberOverloadFunc(createTimeID("requestURI_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("requestURI_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -405,7 +472,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "resolveReference", - MemberOverloadFunc(createTimeID("resolveReference_url_url_url"), URLType, []*cel.Type{URLType}, URLType, + MemberOverloadFunc(createURLID("resolveReference_url_url_url"), URLType, []*cel.Type{URLType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { @@ -424,15 +491,19 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "string", - MemberOverloadFunc(createTimeID("string_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("string_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - return types.String(self.Value().(*URL).String()) + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.String()) }, ), ), BindMemberFunction( "unmarshalBinary", - MemberOverloadFunc(createTimeID("unmarshalBinary_url_bytes_url"), URLType, []*cel.Type{cel.BytesType}, URLType, + MemberOverloadFunc(createURLID("unmarshalBinary_url_bytes_url"), URLType, []*cel.Type{cel.BytesType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { var u url.URL err := u.UnmarshalBinary(args[0].(types.Bytes)) @@ -463,7 +534,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "username", - MemberOverloadFunc(createTimeID("username_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("username_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*Userinfo).GoUserinfo() if err != nil { @@ -475,7 +546,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "password", - MemberOverloadFunc(createTimeID("password_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("password_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*Userinfo).GoUserinfo() if err != nil { @@ -492,7 +563,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "passwordSet", - MemberOverloadFunc(createTimeID("passwordSet_userinfo_bool"), UserinfoType, []*cel.Type{}, cel.BoolType, + MemberOverloadFunc(createURLID("passwordSet_userinfo_bool"), UserinfoType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*Userinfo).GoUserinfo() if err != nil { @@ -505,7 +576,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), BindMemberFunction( "string", - MemberOverloadFunc(createTimeID("string_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("string_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*Userinfo).GoUserinfo() if err != nil { From 71a5688be2b734e43688a1b9710f398ceeabc2ca Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Tue, 17 Sep 2024 19:34:35 +0900 Subject: [PATCH 04/12] =?UTF-8?q?=E2=9C=85=20add=20url=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url_test.go | 430 +++++++++++++++++++++++++++++++- 1 file changed, 427 insertions(+), 3 deletions(-) diff --git a/grpc/federation/cel/url_test.go b/grpc/federation/cel/url_test.go index 8ebcbd23..33dcb199 100644 --- a/grpc/federation/cel/url_test.go +++ b/grpc/federation/cel/url_test.go @@ -3,6 +3,7 @@ package cel_test import ( "context" "fmt" + "github.com/google/go-cmp/cmp/cmpopts" "net/url" "testing" @@ -10,11 +11,10 @@ import ( "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" cellib "github.com/mercari/grpc-federation/grpc/federation/cel" ) -func TestParseURL(t *testing.T) { +func TestURLFunctions(t *testing.T) { tests := []struct { name string expr string @@ -37,12 +37,436 @@ func TestParseURL(t *testing.T) { if err != nil { return err } - if diff := cmp.Diff(gotURL, expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + if diff := cmp.Diff(gotURL, *expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse scheme", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').scheme()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Scheme + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse opaque", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').opaque()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Opaque + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + //TODO user + { + name: "parse host", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').host()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Host + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse path", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').path()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Path + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse raw path", + expr: `grpc.federation.url.parse('https://example.com/%E3%81%82%20%2Fpath?query=1#fragment').rawPath()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/%E3%81%82%20%2Fpath?query=1#fragment") + if err != nil { + return err + } + expected := parse.RawPath + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse force query with empty query", + expr: `grpc.federation.url.parse('https://example.com/path?').forceQuery()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?") + if err != nil { + return err + } + parse.ForceQuery = true + expected := parse.String() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse raw query", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').rawQuery()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.RawQuery + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse fragment", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').fragment()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Fragment + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse raw fragment with escaped fragment", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#frag%20ment').rawFragment()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#frag%20ment") + if err != nil { + return err + } + expected := parse.RawFragment + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse escaped fragment", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').escapedFragment()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.EscapedFragment() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse escaped path", + expr: `grpc.federation.url.parse('https://example.com/pa th?query=1#fragment').escapedPath()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/pa th?query=1#fragment") + if err != nil { + return err + } + expected := parse.EscapedPath() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "parse hostname", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').hostname()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Hostname() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "is abs", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').isAbs()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.Bool) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.IsAbs() + if diff := cmp.Diff(bool(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "join path", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').joinPath(['/new'])`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.URL) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotURL, err := gotV.GoURL() + if err != nil { + return err + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.JoinPath("/new") + if diff := cmp.Diff(gotURL, *expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "marshal binary", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').marshalBinary()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.Bytes) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected, err := parse.MarshalBinary() + if err != nil { + return err + } + if diff := cmp.Diff(gotV.Value(), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "url parse", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').parse('/relativePath')`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.URL) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotURL, err := gotV.GoURL() + if err != nil { + return err + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected, err := parse.Parse("/relativePath") + if err != nil { + return err + } + if diff := cmp.Diff(gotURL, *expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "port", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').port()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Port() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + //{ + // name: "query", + // expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').query()`, + // cmp: func(got ref.Val) error { + // gotV, ok := got.(types.baseMap) + // if !ok { + // return fmt.Errorf("invalid result type: %T", got) + // } + // parse, err := url.Parse("https://example.com/path?query=1#fragment") + // if err != nil { + // return err + // } + // expected := parse.Query() + // if diff := cmp.Diff(gotV, expected); diff != "" { + // return fmt.Errorf("(-got, +want)\n%s", diff) + // } + // return nil + // }, + //}, + { + name: "request uri", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').requestURI()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.RequestURI() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "resolve reference", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').resolveReference(grpc.federation.url.parse('/relativePath'))`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.URL) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotURL, err := gotV.GoURL() + if err != nil { + return err + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + ref, err := url.Parse("/relativePath") + if err != nil { + return err + } + expected := parse.ResolveReference(ref) + if diff := cmp.Diff(gotURL, *expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "string", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').string()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.String() + if diff := cmp.Diff(string(gotV), expected); diff != "" { return fmt.Errorf("(-got, +want)\n%s", diff) } return nil }, }, + //TODO unmarshalBinary } reg, err := types.NewRegistry(new(cellib.URL), new(cellib.Userinfo)) From 62e1747a870a87e931f4053b6e326cdeb6fe7f95 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Wed, 25 Sep 2024 21:25:22 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=F0=9F=90=9B=20fix=20some=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index 40472105..a1c0495e 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -109,7 +109,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { for _, funcOpts := range [][]cel.EnvOption{ BindFunction( createURLName("joinPath"), - OverloadFunc(createURLID("joinPath_string_strings_url"), []*cel.Type{cel.StringType, cel.ListType(cel.StringType)}, URLType, + OverloadFunc(createURLID("joinPath_string_strings_string"), []*cel.Type{cel.StringType, cel.ListType(cel.StringType)}, cel.StringType, func(_ context.Context, args ...ref.Val) ref.Val { base := string(args[0].(types.String)) elems := args[1].(traits.Lister) @@ -218,7 +218,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { ), ), BindMemberFunction( - "user", + "userinfo", // user is not a valid field name MemberOverloadFunc(createURLID("user_url_userinfo"), URLType, []*cel.Type{}, UserinfoType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() @@ -434,6 +434,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), + // func (u *URL) Query() Values : returns map[string][]string BindMemberFunction( "query", MemberOverloadFunc(createURLID("query_url_map"), URLType, []*cel.Type{}, cel.MapType(cel.StringType, cel.ListType(cel.StringType)), @@ -458,6 +459,18 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), + BindMemberFunction( + "redacted", + MemberOverloadFunc(createURLID("redacted_url_string"), URLType, []*cel.Type{}, cel.StringType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.String(v.Redacted()) + }, + ), + ), BindMemberFunction( "requestURI", MemberOverloadFunc(createURLID("requestURI_url_string"), URLType, []*cel.Type{}, cel.StringType, From 334e23a344d1eda858c7341ae68af629394ded94 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Wed, 25 Sep 2024 21:25:40 +0900 Subject: [PATCH 06/12] =?UTF-8?q?=E2=9C=85=20add=20remaining=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url_test.go | 374 ++++++++++++++++++++++++++++++-- 1 file changed, 351 insertions(+), 23 deletions(-) diff --git a/grpc/federation/cel/url_test.go b/grpc/federation/cel/url_test.go index 33dcb199..dc68a38f 100644 --- a/grpc/federation/cel/url_test.go +++ b/grpc/federation/cel/url_test.go @@ -3,8 +3,10 @@ package cel_test import ( "context" "fmt" + "github.com/google/cel-go/common/types/traits" "github.com/google/go-cmp/cmp/cmpopts" "net/url" + "strings" "testing" "github.com/google/cel-go/cel" @@ -21,6 +23,92 @@ func TestURLFunctions(t *testing.T) { args map[string]any cmp func(ref.Val) error }{ + { + name: "join path", + expr: `grpc.federation.url.joinPath('https://example.com/path?query=1#fragment', ['/new'])`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + expected, err := url.JoinPath("https://example.com/path?query=1#fragment", "/new") + if err != nil { + return err + } + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "path escape", + expr: `grpc.federation.url.pathEscape('あ /')`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + expected := url.PathEscape("あ /") + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "path unescape", + expr: `grpc.federation.url.pathUnescape('%E3%81%82%20%2F')`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + expected, err := url.PathUnescape("%E3%81%82%20%2F") + if err != nil { + return err + } + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "query escape", + expr: `grpc.federation.url.queryEscape('あ /')`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + expected := url.QueryEscape("あ /") + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "query unescape", + expr: `grpc.federation.url.queryUnescape('%E3%81%82%20%2F')`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + expected, err := url.QueryUnescape("%E3%81%82%20%2F") + if err != nil { + return err + } + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + + // url functions { name: "parse", expr: "grpc.federation.url.parse('https://example.com/path?query=1#fragment')", @@ -43,6 +131,28 @@ func TestURLFunctions(t *testing.T) { return nil }, }, + { + name: "parse request uri", + expr: `grpc.federation.url.parseRequestURI('https://example.com/path?query=1#fragment')`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.URL) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotURL, err := gotV.GoURL() + if err != nil { + return err + } + expected, err := url.ParseRequestURI("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + if diff := cmp.Diff(gotURL, *expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, { name: "parse scheme", expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').scheme()`, @@ -81,7 +191,29 @@ func TestURLFunctions(t *testing.T) { return nil }, }, - //TODO user + { + name: "parse user", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').userinfo()`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.Userinfo) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotUser, err := gotV.GoUserinfo() + if err != nil { + return err + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.User + if diff := userinfoDiff(gotUser, expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, { name: "parse host", expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').host()`, @@ -140,7 +272,7 @@ func TestURLFunctions(t *testing.T) { }, }, { - name: "parse force query with empty query", + name: "parse force query", expr: `grpc.federation.url.parse('https://example.com/path?').forceQuery()`, cmp: func(got ref.Val) error { gotV, ok := got.(types.String) @@ -198,7 +330,7 @@ func TestURLFunctions(t *testing.T) { }, }, { - name: "parse raw fragment with escaped fragment", + name: "parse raw fragment", expr: `grpc.federation.url.parse('https://example.com/path?query=1#frag%20ment').rawFragment()`, cmp: func(got ref.Val) error { gotV, ok := got.(types.String) @@ -382,25 +514,59 @@ func TestURLFunctions(t *testing.T) { return nil }, }, - //{ - // name: "query", - // expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').query()`, - // cmp: func(got ref.Val) error { - // gotV, ok := got.(types.baseMap) - // if !ok { - // return fmt.Errorf("invalid result type: %T", got) - // } - // parse, err := url.Parse("https://example.com/path?query=1#fragment") - // if err != nil { - // return err - // } - // expected := parse.Query() - // if diff := cmp.Diff(gotV, expected); diff != "" { - // return fmt.Errorf("(-got, +want)\n%s", diff) - // } - // return nil - // }, - //}, + { + name: "query", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').query()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(traits.Mapper) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotQueryMap := make(map[string][]string) + it := gotV.Iterator() + for it.HasNext() == types.True { + key := it.Next() + keyStr := string(key.(types.String)) + valueList := gotV.Get(key).(traits.Lister) + + var values []string + for i := int64(0); i < int64(valueList.Size().(types.Int)); i++ { + values = append(values, string(valueList.Get(types.Int(i)).(types.String))) + } + gotQueryMap[keyStr] = values + } + + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := map[string][]string(parse.Query()) + + if diff := cmp.Diff(gotQueryMap, expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "redacted", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').redacted()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse.Redacted() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, { name: "request uri", expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').requestURI()`, @@ -466,7 +632,145 @@ func TestURLFunctions(t *testing.T) { return nil }, }, - //TODO unmarshalBinary + { + name: "unmarshal binary", + expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').unmarshalBinary(grpc.federation.url.parse('https://example.com/path?query=1#fragment').marshalBinary())`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.URL) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotURL, err := gotV.GoURL() + if err != nil { + return err + } + parse, err := url.Parse("https://example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := parse + if diff := cmp.Diff(gotURL, *expected, cmpopts.IgnoreUnexported(url.URL{})); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + + // userinfo tests + { + name: "user", + expr: `grpc.federation.url.user('username')`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.Userinfo) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotUser, err := gotV.GoUserinfo() + if err != nil { + return err + } + expected := url.User("username") + if diff := userinfoDiff(gotUser, expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "user password to user info", + expr: `grpc.federation.url.userPassword('username', 'password')`, + cmp: func(got ref.Val) error { + gotV, ok := got.Value().(*cellib.Userinfo) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + gotUser, err := gotV.GoUserinfo() + if err != nil { + return err + } + expected := url.UserPassword("username", "password") + if diff := userinfoDiff(gotUser, expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "user username", + expr: `grpc.federation.url.parse('https://username:password@example.com/path?query=1#fragment').userinfo().username()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + user, err := url.Parse("https://username:password@example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := user.User.Username() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "user password", + expr: `grpc.federation.url.parse('https://username:password@example.com/path?query=1#fragment').userinfo().password()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + user, err := url.Parse("https://username:password@example.com/path?query=1#fragment") + if err != nil { + return err + } + expected, _ := user.User.Password() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "user password set", + expr: `grpc.federation.url.parse('https://username:password@example.com/path?query=1#fragment').userinfo().passwordSet()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.Bool) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + user, err := url.Parse("https://username:password@example.com/path?query=1#fragment") + if err != nil { + return err + } + _, expected := user.User.Password() + if diff := cmp.Diff(bool(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, + { + name: "user string", + expr: `grpc.federation.url.parse('https://username:password@example.com/path?query=1#fragment').userinfo().string()`, + cmp: func(got ref.Val) error { + gotV, ok := got.(types.String) + if !ok { + return fmt.Errorf("invalid result type: %T", got) + } + user, err := url.Parse("https://username:password@example.com/path?query=1#fragment") + if err != nil { + return err + } + expected := user.User.String() + if diff := cmp.Diff(string(gotV), expected); diff != "" { + return fmt.Errorf("(-got, +want)\n%s", diff) + } + return nil + }, + }, } reg, err := types.NewRegistry(new(cellib.URL), new(cellib.Userinfo)) @@ -504,3 +808,27 @@ func TestURLFunctions(t *testing.T) { }) } } + +// UserinfoDiff compares two Userinfo structs and returns a diff string similar to cmp.Diff. +func userinfoDiff(got, expected *url.Userinfo) string { + var diffs []string + + if got.Username() != expected.Username() { + diffs = append(diffs, fmt.Sprintf("username: got %q, want %q", got.Username(), expected.Username())) + } + + gotPassword, gotPasswordSet := got.Password() + expectedPassword, expectedPasswordSet := expected.Password() + if gotPasswordSet != expectedPasswordSet { + diffs = append(diffs, fmt.Sprintf("password set: got %t, want %t", gotPasswordSet, expectedPasswordSet)) + } + if gotPassword != expectedPassword { + diffs = append(diffs, fmt.Sprintf("password: got %q, want %q", gotPassword, expectedPassword)) + } + + if len(diffs) == 0 { + return "" + } + + return "(-got, +want)\n" + strings.Join(diffs, "\n") +} From 7b5b20b6e9d5bfa0cc2b5abaf0ebc3897e9fe009 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Thu, 26 Sep 2024 18:09:06 +0900 Subject: [PATCH 07/12] =?UTF-8?q?=F0=9F=93=9D=20add=20url.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cel/url.md | 609 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 609 insertions(+) create mode 100644 docs/cel/url.md diff --git a/docs/cel/url.md b/docs/cel/url.md new file mode 100644 index 00000000..2b807cc0 --- /dev/null +++ b/docs/cel/url.md @@ -0,0 +1,609 @@ +# grpc.federation.url APIs + +The API for this package was created based on Go's [`net/url`](https://pkg.go.dev/net/url) package. + +# Index + +## Functions + +- [`joinPath`](#joinPath) +- [`pathEscape`](#pathEscape) +- [`pathUnescape`](#pathUnescape) +- [`queryEscape`](#queryEscape) +- [`queryUnescape`](#queryUnescape) + +## URL + +- [`parse`](#parse) +- [`parseRequestURI`](#parseRequestURI) +- [`URL.scheme`](#urlscheme) +- [`URL.opaque`](#urlopaque) +- [`URL.userinfo`](#urluserinfo) +- [`URL.host`](#urlhost) +- [`URL.path`](#urlpath) +- [`URL.rawPath`](#urlrawpath) +- [`URL.forceQuery`](#urlforceQuery) +- [`URL.rawQuery`](#urlrawQuery) +- [`URL.fragment`](#urlfragment) +- [`URL.rawFragment`](#urlrawFragment) +- [`URL.escapedFragment`](#urlescapedFragment) +- [`URL.escapedPath`](#urlescapedPath) +- [`URL.hostname`](#urlhostname) +- [`URL.isAbs`](#urlisAbs) +- [`URL.joinPath`](#urljoinPath) +- [`URL.marshalBinary`](#urlmarshalBinary) +- [`URL.parse`](#urlparse) +- [`URL.port`](#urlport) +- [`URL.query`](#urlquery) +- [`URL.redacted`](#urlredacted) +- [`URL.requestURI`](#urlrequestURI) +- [`URL.resolveReference`](#urlresolveReference) +- [`URL.string`](#urlstring) +- [`URL.unmarshalBinary`](#urlunmarshalBinary) + +## Userinfo + +- [`user`](#user) +- [`userPassword`](#userPassword) +- [`Userinfo.username`](#userinfousername) +- [`Userinfo.password`](#userinfopassword) +- [`Userinfo.passwordSet`](#userinfopasswordSet) +- [`Userinfo.string`](#userinfostring) + +# Functions + +## joinPath + +`joinPath` concatenates a base URL with additional path elements to form a complete URL. + +### Parameters + +`joinPath(baseURL string, elements []string) string` + +- `baseURL`: the base URL to start with. +- `elements`: an array of path segments to join with the base URL. + +### Example + +```cel +grpc.federation.url.joinPath("https://example.com", ["path", "to", "resource"]) //=> "https://example.com/path/to/resource" +``` + +## pathEscape + +`pathEscape` escapes the string so it can be safely placed inside a URL path segment. + +### Parameters + +`pathEscape(path string) string` + +- `path`: the path segment to escape. + +### Examples + +```cel +grpc.federation.url.pathEscape("/path with spaces/") +``` + +## pathUnescape + +`pathUnescape` unescapes a path segment. + +### Parameters + +`pathUnescape(path string) string` + +- `path`: the path segment to unescape. + +### Examples + +```cel +grpc.federation.url.pathUnescape("/path%20with%20spaces/") +``` + +## queryEscape + +`queryEscape` escapes the string so it can be safely placed inside a URL query. + +### Parameters + +`queryEscape(query string) string` + +- `query`: the query string to escape. + +### Examples + +```cel +grpc.federation.url.queryEscape("query with spaces") +``` + +## queryUnescape + +`queryUnescape` unescapes a query string. + +### Parameters + +`queryUnescape(query string) string` + +- `query`: the query string to unescape. + +### Examples + +```cel +grpc.federation.url.queryUnescape("query%20with%20spaces") +``` + +# URL Methods + +## parse + +`parse` parses a URL and returns a URL struct. + +### Parameters + +`parse(url string) URL` + +- `url`: the URL string to parse. + +### Examples + +```cel +grpc.federation.url.parse("https://www.example.com/path?query=value#fragment") +``` + +## parseRequestURI + +`parseRequestURI` parses a URL in request context and returns a URL struct. + +### Parameters + +`parseRequestURI(requestURI string) URL` + +- `requestURI`: the URI for a request. + +### Examples + +```cel +grpc.federation.url.parseRequestURI("/path?query=value#fragment") +``` + +## URL.scheme + +`scheme` returns the scheme of the URL. + +### Parameters + +`URL.scheme() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com").scheme() //=> "https" +``` + +## URL.opaque + +`opaque` returns the opaque part of the URL. + +### Parameters + +`URL.opaque() string` + +### Examples + +```cel +grpc.federation.url.parse("mailto:John.Doe@example.com").opaque() //=> "John.Doe@example.com" +``` + +## URL.userinfo + +`userinfo` returns the user information in the URL. + +### Parameters + +`URL.userinfo() Userinfo` + +### Examples + +```cel +grpc.federation.url.parse("https://user:pass@example.com").userinfo() //=> grpc.federation.url.Userinfo{username: "user", password: "pass"} +``` + +## URL.host + +`host` returns the host of the URL. + +### Parameters + +`URL.host() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com").host() //=> "example.com" +``` + +## URL.path + +`path` returns the path of the URL. + +### Parameters + +`URL.path() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com/path").path() //=> "/path" +``` + +## URL.rawPath + +`rawPath` returns the raw path of the URL. + +### Parameters + +`URL.rawPath() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com/%2Fpath%2F").rawPath() //=> "/%2Fpath%2F" +``` + +## URL.forceQuery + +`forceQuery` returns the URL string with the ForceQuery field set to true. + +### Parameters + +`URL.forceQuery() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com").forceQuery() +``` +## URL.rawQuery + +`rawQuery` returns the raw query string of the URL. + +### Parameters + +`URL.rawQuery() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com?query=value").rawQuery() //=> "query=value" +``` + +## URL.fragment + +`fragment` returns the fragment of the URL. + +### Parameters + +`URL.fragment() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com#fragment").fragment() //=> "fragment" +``` + +## URL.rawFragment + +`rawFragment` returns the raw fragment of the URL. + +### Parameters + +`URL.rawFragment() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com#fragment").rawFragment() //=> "fragment" +``` + +## URL.escapedFragment + +`escapedFragment` returns the escaped fragment of the URL. + +### Parameters + +`URL.escapedFragment() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com#frag ment").escapedFragment() //=> "frag%20ment" +``` + +## URL.escapedPath + +`escapedPath` returns the escaped path of the URL. + +### Parameters + +`URL.escapedPath() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com/path with spaces").escapedPath() //=> "/path%20with%20spaces" +``` + +## URL.hostname + +`hostname` returns the host name of the URL. + +### Parameters + +`URL.hostname() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com:8080").hostname() //=> "example.com" +``` + +## URL.isAbs + +`isAbs` reports whether the URL is absolute. + +### Parameters + +`URL.isAbs() bool` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com").isAbs() //=> true +grpc.federation.url.parse("/path").isAbs() //=> false +``` + +## URL.joinPath + +`joinPath` joins the path elements with the URL path. + +### Parameters + +`URL.joinPath(elements []string) URL` + +- `elements`: list of path elements to join with the URL path. + +### Examples + +```cel +grpc.federation.url.parse("https://example.com/path").joinPath(["to", "resource"]) //=> "https://example.com/path/to/resource" +``` + +## URL.marshalBinary + +`marshalBinary` returns the URL in a binary format. + +### Parameters + +`URL.marshalBinary() bytes` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com").marshalBinary() +``` + +## URL.parse + +`parse` parses a URL string in the context of the current URL. + +### Parameters + +`URL.parse(ref string) URL` + +- `ref`: the URL reference string to parse. + +### Examples + +```cel +grpc.federation.url.parse("https://example.com/base").parse("/resource") //=> "https://example.com/resource" +``` + +## URL.port + +`port` returns the port of the URL. + +### Parameters + +`URL.port() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com:8080").port() //=> "8080" +``` + +## URL.query + +`query` returns the parsed query parameters of the URL. + +### Parameters + +`URL.query() map` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com?key=value&key=another").query() //=> {"key": ["value", "another"]} +``` + +## URL.redacted + +`redacted` returns the URL with password part redacted. + +### Parameters + +`URL.redacted() string` + +### Examples + +```cel +grpc.federation.url.parse("https://user:password@example.com").redacted() //=> "https://user:xxxxx@example.com" +``` + +## URL.requestURI + +`requestURI` returns the request URI of the URL. + +### Parameters + +`URL.requestURI() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com/path?query=value").requestURI() //=> "/path?query=value" +``` + +## URL.resolveReference + +`resolveReference` resolves a reference URL against the base URL. + +### Parameters + +`URL.resolveReference(ref URL) URL` + +- `ref`: the reference URL to resolve. + +### Examples + +```cel +base := grpc.federation.url.parse("https://example.com/base") +ref := grpc.federation.url.parse("/resource") +base.resolveReference(ref) //=> "https://example.com/resource" +``` + +## URL.string + +`string` returns the URL as a string. + +### Parameters + +`URL.string() string` + +### Examples + +```cel +grpc.federation.url.parse("https://example.com").string() +``` + +## URL.unmarshalBinary + +`unmarshalBinary` unmarshals a binary format URL into a URL struct. + +### Parameters + +`URL.unmarshalBinary(data bytes) URL` + +- `data`: binary format URL data. + +### Examples + +```cel +url := grpc.federation.url.parse("https://example.com") +binaryData := url.marshalBinary() +grpc.federation.url.parse("https://example.com").unmarshalBinary(binaryData) +``` + +# Userinfo Methods + +## user + +`user` returns a Userinfo object with the provided username. + +### Parameters + +`user(username string) Userinfo` + +- `username`: the username for the userinfo. + +### Examples + +```cel +grpc.federation.url.user("user") +``` + +## userPassword + +`userPassword` returns a Userinfo object with the provided username and password. + +### Parameters + +`userPassword(username string, password string) Userinfo` + +- `username`: the username for the userinfo. +- `password`: the password for the userinfo. + +### Examples + +```cel +grpc.federation.url.userPassword("user", "password") +``` + +## Userinfo.username + +`username` returns the username of the Userinfo. + +### Parameters + +`Userinfo.username() string` + +### Examples + +```cel +grpc.federation.url.user("user").username() //=> "user" +``` + +## Userinfo.password + +`password` returns the password of the Userinfo, if set. + +### Parameters + +`Userinfo.password() string` + +### Examples + +```cel +grpc.federation.url.userPassword("user", "password").password() //=> "password" +``` + +## Userinfo.passwordSet + +`passwordSet` returns true if the password is set for the Userinfo. + +### Parameters + +`Userinfo.passwordSet() bool` + +### Examples + +```cel +grpc.federation.url.userPassword("user", "password").passwordSet() //=> true +grpc.federation.url.user("user").passwordSet() //=> false +``` + +## Userinfo.string + +`string` returns the Userinfo as a string. + +### Parameters + +`Userinfo.string() string` + +### Examples + +```cel +grpc.federation.url.userPassword("user", "password").string() //=> "user:password" +grpc.federation.url.user("user").string() //=> "user" +``` From 3a23f78bfec3247f8883bc1e885a86298e2afdee Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Thu, 26 Sep 2024 18:33:24 +0900 Subject: [PATCH 08/12] =?UTF-8?q?=F0=9F=9A=A8=20fix=20lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url.go | 10 +++++----- grpc/federation/cel/url_test.go | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index a1c0495e..05c39cf1 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -2,11 +2,12 @@ package cel import ( "context" + "net/url" + "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" - "net/url" ) const URLPackageName = "url" @@ -381,6 +382,9 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { } v.Path, err = url.JoinPath(v.Path, paths...) + if err != nil { + return types.NewErr(err.Error()) + } return lib.toURLValue(v) }, @@ -448,10 +452,6 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { queryParams := v.Query() queryMap := map[ref.Val]ref.Val{} for key, values := range queryParams { - var valueList []ref.Val - for _, val := range values { - valueList = append(valueList, types.String(val)) - } queryMap[types.String(key)] = types.NewStringList(adapter, values) } diff --git a/grpc/federation/cel/url_test.go b/grpc/federation/cel/url_test.go index dc68a38f..809c2ba9 100644 --- a/grpc/federation/cel/url_test.go +++ b/grpc/federation/cel/url_test.go @@ -3,8 +3,6 @@ package cel_test import ( "context" "fmt" - "github.com/google/cel-go/common/types/traits" - "github.com/google/go-cmp/cmp/cmpopts" "net/url" "strings" "testing" @@ -12,7 +10,10 @@ import ( "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + cellib "github.com/mercari/grpc-federation/grpc/federation/cel" ) @@ -425,7 +426,7 @@ func TestURLFunctions(t *testing.T) { }, }, { - name: "join path", + name: "url join path", expr: `grpc.federation.url.parse('https://example.com/path?query=1#fragment').joinPath(['/new'])`, cmp: func(got ref.Val) error { gotV, ok := got.Value().(*cellib.URL) From 3279e04770dea83ee83f2768723e53869ca3e5e8 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Mon, 30 Sep 2024 20:22:16 +0900 Subject: [PATCH 09/12] =?UTF-8?q?=F0=9F=90=9B=20fix=20some=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url.go | 52 +++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index 05c39cf1..de351295 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -28,24 +28,28 @@ func (x *URL) GoURL() (url.URL, error) { } return url.URL{ - Scheme: x.GetScheme(), - Opaque: x.GetOpaque(), - User: user, - Host: x.GetHost(), - Path: x.GetPath(), - RawPath: x.GetRawPath(), - ForceQuery: x.GetForceQuery(), - RawQuery: x.GetRawQuery(), - Fragment: x.GetFragment(), + Scheme: x.GetScheme(), + Opaque: x.GetOpaque(), + User: user, + Host: x.GetHost(), + Path: x.GetPath(), + RawPath: x.GetRawPath(), + OmitHost: x.GetOmitHost(), + ForceQuery: x.GetForceQuery(), + RawQuery: x.GetRawQuery(), + Fragment: x.GetFragment(), + RawFragment: x.GetRawFragment(), }, nil } func (x *Userinfo) GoUserinfo() (*url.Userinfo, error) { + if x == nil { + return nil, nil + } if x.GetPasswordSet() { return url.UserPassword(x.GetUsername(), x.GetPassword()), nil - } else { - return url.User(x.GetUsername()), nil } + return url.User(x.GetUsername()), nil } var _ cel.SingletonLibrary = new(URLLibrary) @@ -267,17 +271,27 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { }, ), ), - // forceQuery is changed to return String + BindMemberFunction( + "omitHost", + MemberOverloadFunc(createURLID("omitHost_url_bool"), URLType, []*cel.Type{}, cel.BoolType, + func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { + v, err := self.Value().(*URL).GoURL() + if err != nil { + return types.NewErr(err.Error()) + } + return types.Bool(v.OmitHost) + }, + ), + ), BindMemberFunction( "forceQuery", - MemberOverloadFunc(createURLID("forceQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, + MemberOverloadFunc(createURLID("forceQuery_url_string"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { v, err := self.Value().(*URL).GoURL() if err != nil { return types.NewErr(err.Error()) } - v.ForceQuery = true - return types.String(v.String()) + return types.Bool(v.ForceQuery) }, ), ), @@ -565,12 +579,8 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { if err != nil { return types.NewErr(err.Error()) } - password, hasPassword := v.Password() - if hasPassword { - return types.String(password) - } else { - return types.String("") - } + password, _ := v.Password() + return types.String(password) }, ), ), From a524494c6b5c8c6596ca0ebcae4033c81e153959 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Mon, 30 Sep 2024 21:05:31 +0900 Subject: [PATCH 10/12] =?UTF-8?q?=F0=9F=90=9B=20fix=20conflict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../02_simple/federation/federation.pb.go | 412 +++++++++--------- .../federation_grpc_federation.pb.go | 4 +- .../proto/federation/federation.proto | 2 +- grpc/federation/cel/url_test.go | 10 +- 4 files changed, 212 insertions(+), 216 deletions(-) diff --git a/_examples/02_simple/federation/federation.pb.go b/_examples/02_simple/federation/federation.pb.go index 894f3cc8..ac2f0707 100644 --- a/_examples/02_simple/federation/federation.pb.go +++ b/_examples/02_simple/federation/federation.pb.go @@ -1176,7 +1176,7 @@ var file_federation_federation_proto_rawDesc = []byte{ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xe8, 0x1e, 0x0a, 0x0f, 0x47, 0x65, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xec, 0x1e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x42, 0x09, 0x9a, @@ -1354,216 +1354,216 @@ var file_federation_federation_proto_rawDesc = []byte{ 0x12, 0x34, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0x9a, 0x4a, 0x0e, 0x12, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x75, 0x72, 0x6c, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0x9a, - 0x4a, 0x17, 0x12, 0x15, 0x75, 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x52, 0x0b, 0x75, 0x72, 0x6c, 0x55, 0x73, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x3a, 0xce, 0x07, 0x9a, 0x4a, 0xca, 0x07, 0x0a, 0x1a, 0x0a, 0x04, 0x70, 0x6f, - 0x73, 0x74, 0x6a, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, 0x0a, 0x02, 0x69, 0x64, - 0x12, 0x04, 0x24, 0x2e, 0x69, 0x64, 0x0a, 0x42, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5a, 0x32, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, - 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x5b, 0x27, 0x61, 0x27, 0x2c, 0x20, 0x27, 0x62, 0x27, 0x2c, 0x20, - 0x27, 0x63, 0x27, 0x5d, 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x4f, 0x0a, 0x03, 0x75, 0x72, - 0x6c, 0x5a, 0x48, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x75, 0x72, 0x6c, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x27, 0x68, 0x74, - 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x3a, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x27, 0x29, 0x0a, 0x59, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x65, 0x5a, 0x51, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x28, 0x32, - 0x30, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x32, 0x35, 0x2c, 0x20, 0x31, 0x32, 0x2c, - 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x67, 0x72, 0x70, 0x63, 0x2e, - 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x55, 0x54, 0x43, 0x28, 0x29, 0x29, 0x0a, 0x3a, 0x0a, 0x0b, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5a, 0x2b, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x28, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x75, 0x6e, 0x69, 0x78, 0x28, - 0x29, 0x29, 0x0a, 0x33, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x64, - 0x5a, 0x25, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x28, 0x72, 0x61, 0x6e, 0x64, 0x5f, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x0a, 0x3b, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x5a, - 0x33, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x75, 0x75, 0x69, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, - 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x61, 0x6e, 0x64, 0x28, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, - 0x61, 0x6e, 0x64, 0x29, 0x0a, 0x36, 0x0a, 0x03, 0x6c, 0x6f, 0x63, 0x5a, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x27, - 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x27, 0x29, 0x0a, 0x45, 0x0a, 0x07, - 0x6a, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x3a, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, + 0x67, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x42, 0x0a, 0x0d, 0x75, 0x72, 0x6c, 0x5f, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0x9a, + 0x4a, 0x1b, 0x12, 0x19, 0x75, 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, + 0x28, 0x29, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x52, 0x0b, 0x75, + 0x72, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x61, + 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0xce, 0x07, 0x9a, 0x4a, 0xca, 0x07, 0x0a, 0x1a, + 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x6a, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, + 0x0a, 0x02, 0x69, 0x64, 0x12, 0x04, 0x24, 0x2e, 0x69, 0x64, 0x0a, 0x42, 0x0a, 0x0c, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5a, 0x32, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x5b, 0x27, 0x61, 0x27, 0x2c, 0x20, 0x27, + 0x62, 0x27, 0x2c, 0x20, 0x27, 0x63, 0x27, 0x5d, 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x4f, + 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x5a, 0x48, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x75, 0x72, 0x6c, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x28, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x40, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x27, 0x29, 0x0a, + 0x59, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x5a, 0x51, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x28, 0x32, 0x30, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x32, 0x35, 0x2c, - 0x20, 0x31, 0x32, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6c, - 0x6f, 0x63, 0x29, 0x0a, 0x38, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x5a, 0x2e, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, - 0x28, 0x29, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x31, 0x27, 0x5d, 0x5b, 0x30, 0x5d, 0x0a, 0x08, 0x0a, - 0x01, 0x61, 0x6a, 0x03, 0x0a, 0x01, 0x41, 0x0a, 0x2b, 0x0a, 0x0d, 0x73, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5a, 0x1a, 0x5b, 0x34, 0x2c, 0x20, 0x31, 0x2c, - 0x20, 0x33, 0x2c, 0x20, 0x32, 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x41, 0x73, 0x63, 0x28, 0x76, - 0x2c, 0x20, 0x76, 0x29, 0x0a, 0x95, 0x01, 0x0a, 0x0c, 0x73, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, - 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5a, 0x84, 0x01, 0x5b, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, - 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x61, - 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x61, 0x27, 0x7d, 0x7d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x62, 0x27, 0x7d, 0x7d, 0x5d, 0x2e, 0x73, - 0x6f, 0x72, 0x74, 0x44, 0x65, 0x73, 0x63, 0x28, 0x76, 0x2c, 0x20, 0x76, 0x2e, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x31, 0x29, 0x0a, 0x25, 0x0a, 0x09, - 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x18, 0x7b, 0x31, 0x3a, 0x20, 0x27, - 0x61, 0x27, 0x2c, 0x20, 0x32, 0x3a, 0x20, 0x27, 0x62, 0x27, 0x2c, 0x20, 0x33, 0x3a, 0x20, 0x27, - 0x63, 0x27, 0x7d, 0x0a, 0x12, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x5a, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x0a, 0x4b, 0x5a, 0x49, 0x67, 0x72, 0x70, 0x63, 0x2e, - 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x69, - 0x6e, 0x66, 0x6f, 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, 0x70, - 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x27, 0x3a, 0x20, 0x70, 0x6f, - 0x73, 0x74, 0x7d, 0x29, 0x22, 0xdf, 0x03, 0x0a, 0x01, 0x41, 0x12, 0x25, 0x0a, 0x01, 0x62, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x42, 0x06, 0x9a, 0x4a, 0x03, 0x12, 0x01, 0x62, 0x52, 0x01, - 0x62, 0x1a, 0xa1, 0x03, 0x0a, 0x01, 0x42, 0x12, 0x2d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, 0x03, 0x66, 0x6f, - 0x6f, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x2d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, 0x03, 0x62, 0x61, 0x72, - 0x52, 0x03, 0x62, 0x61, 0x72, 0x1a, 0x24, 0x0a, 0x01, 0x43, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x9a, 0x4a, 0x08, 0x12, 0x06, 0x24, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x97, 0x02, 0x9a, 0x4a, - 0x93, 0x02, 0x0a, 0x1d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x6a, 0x16, 0x0a, 0x05, 0x41, 0x2e, 0x42, - 0x2e, 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, 0x66, 0x6f, 0x6f, - 0x27, 0x0a, 0x1d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x6a, 0x16, 0x0a, 0x05, 0x41, 0x2e, 0x42, 0x2e, - 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, 0x62, 0x61, 0x72, 0x27, - 0x0a, 0x89, 0x01, 0x12, 0x11, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, - 0x20, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x5a, 0x74, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x69, 0x6e, 0x66, 0x6f, - 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x27, 0x3a, 0x20, 0x5b, 0x66, 0x6f, 0x6f, 0x2c, 0x20, 0x62, 0x61, 0x72, - 0x5d, 0x2c, 0x20, 0x27, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x27, - 0x3a, 0x20, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2c, 0x20, 0x27, - 0x62, 0x61, 0x72, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x7d, 0x7d, 0x29, 0x0a, 0x47, 0x5a, 0x45, - 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x27, - 0x62, 0x61, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x7d, 0x29, 0x3a, 0x0f, 0x9a, 0x4a, 0x0c, 0x0a, 0x0a, 0x0a, 0x01, 0x62, 0x6a, - 0x05, 0x0a, 0x03, 0x41, 0x2e, 0x42, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, - 0x2f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, - 0x09, 0x9a, 0x4a, 0x06, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x3a, 0x6d, 0x9a, 0x4a, 0x6a, 0x0a, 0x3c, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x35, 0x0a, 0x18, - 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2f, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x04, - 0x24, 0x2e, 0x69, 0x64, 0x1a, 0x03, 0x31, 0x30, 0x73, 0x22, 0x08, 0x0a, 0x06, 0x0a, 0x02, 0x32, - 0x73, 0x10, 0x03, 0x0a, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x5a, 0x08, 0x72, - 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x0a, 0x16, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x6a, - 0x0e, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x06, 0x1a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x22, - 0xc8, 0x04, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x05, - 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x66, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x0a, - 0x06, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x20, 0x31, 0x32, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x55, 0x54, 0x43, 0x28, 0x29, 0x29, 0x0a, 0x3a, 0x0a, 0x0b, 0x72, 0x61, + 0x6e, 0x64, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5a, 0x2b, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, + 0x6e, 0x65, 0x77, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x28, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x75, + 0x6e, 0x69, 0x78, 0x28, 0x29, 0x29, 0x0a, 0x33, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, + 0x72, 0x61, 0x6e, 0x64, 0x5a, 0x25, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x28, 0x72, + 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x0a, 0x3b, 0x0a, 0x04, 0x75, + 0x75, 0x69, 0x64, 0x5a, 0x33, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x75, 0x75, 0x69, 0x64, 0x2e, 0x6e, 0x65, 0x77, 0x52, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x61, 0x6e, 0x64, 0x28, 0x66, 0x69, 0x78, + 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x29, 0x0a, 0x36, 0x0a, 0x03, 0x6c, 0x6f, 0x63, 0x5a, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x27, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x27, 0x29, + 0x0a, 0x45, 0x0a, 0x07, 0x6a, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x3a, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x28, 0x32, 0x30, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x32, 0x2c, + 0x20, 0x32, 0x35, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x35, 0x2c, 0x20, + 0x30, 0x2c, 0x20, 0x6c, 0x6f, 0x63, 0x29, 0x0a, 0x38, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x31, 0x5a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x63, 0x6f, + 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x31, 0x27, 0x5d, 0x5b, 0x30, + 0x5d, 0x0a, 0x08, 0x0a, 0x01, 0x61, 0x6a, 0x03, 0x0a, 0x01, 0x41, 0x0a, 0x2b, 0x0a, 0x0d, 0x73, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5a, 0x1a, 0x5b, 0x34, + 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x33, 0x2c, 0x20, 0x32, 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x41, + 0x73, 0x63, 0x28, 0x76, 0x2c, 0x20, 0x76, 0x29, 0x0a, 0x95, 0x01, 0x0a, 0x0c, 0x73, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5a, 0x84, 0x01, 0x5b, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x61, 0x27, 0x7d, 0x7d, 0x2c, 0x20, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x31, 0x3a, 0x27, 0x62, 0x27, 0x7d, + 0x7d, 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x44, 0x65, 0x73, 0x63, 0x28, 0x76, 0x2c, 0x20, 0x76, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x31, 0x29, + 0x0a, 0x25, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x18, 0x7b, + 0x31, 0x3a, 0x20, 0x27, 0x61, 0x27, 0x2c, 0x20, 0x32, 0x3a, 0x20, 0x27, 0x62, 0x27, 0x2c, 0x20, + 0x33, 0x3a, 0x20, 0x27, 0x63, 0x27, 0x7d, 0x0a, 0x12, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x0a, 0x4b, 0x5a, 0x49, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, + 0x6f, 0x67, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, + 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, + 0x20, 0x7b, 0x27, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x27, + 0x3a, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x7d, 0x29, 0x22, 0xdf, 0x03, 0x0a, 0x01, 0x41, 0x12, 0x25, + 0x0a, 0x01, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x42, 0x06, 0x9a, 0x4a, 0x03, 0x12, + 0x01, 0x62, 0x52, 0x01, 0x62, 0x1a, 0xa1, 0x03, 0x0a, 0x01, 0x42, 0x12, 0x2d, 0x0a, 0x03, 0x66, + 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, + 0x12, 0x03, 0x66, 0x6f, 0x6f, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x2d, 0x0a, 0x03, 0x62, 0x61, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x42, 0x08, 0x9a, 0x4a, 0x05, 0x12, + 0x03, 0x62, 0x61, 0x72, 0x52, 0x03, 0x62, 0x61, 0x72, 0x1a, 0x24, 0x0a, 0x01, 0x43, 0x12, 0x1f, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x9a, 0x4a, + 0x08, 0x12, 0x06, 0x24, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x3a, + 0x97, 0x02, 0x9a, 0x4a, 0x93, 0x02, 0x0a, 0x1d, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x6a, 0x16, 0x0a, + 0x05, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, + 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x0a, 0x1d, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x6a, 0x16, 0x0a, 0x05, + 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x12, 0x0d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x05, 0x27, + 0x62, 0x61, 0x72, 0x27, 0x0a, 0x89, 0x01, 0x12, 0x11, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x5a, 0x74, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, + 0x69, 0x6e, 0x66, 0x6f, 0x28, 0x27, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x65, 0x64, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x67, 0x27, 0x2c, 0x20, 0x7b, 0x27, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x27, 0x3a, 0x20, 0x5b, 0x66, 0x6f, 0x6f, 0x2c, + 0x20, 0x62, 0x61, 0x72, 0x5d, 0x2c, 0x20, 0x27, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x6d, 0x61, 0x70, 0x27, 0x3a, 0x20, 0x7b, 0x27, 0x66, 0x6f, 0x6f, 0x27, 0x3a, 0x20, 0x66, 0x6f, + 0x6f, 0x2c, 0x20, 0x27, 0x62, 0x61, 0x72, 0x27, 0x3a, 0x20, 0x62, 0x61, 0x72, 0x7d, 0x7d, 0x29, + 0x0a, 0x47, 0x5a, 0x45, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x7b, 0x27, 0x66, 0x6f, + 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x27, 0x3a, 0x20, 0x66, 0x6f, 0x6f, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x20, 0x27, 0x62, 0x61, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x27, 0x3a, 0x20, 0x62, + 0x61, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x7d, 0x29, 0x3a, 0x0f, 0x9a, 0x4a, 0x0c, 0x0a, 0x0a, + 0x0a, 0x01, 0x62, 0x6a, 0x05, 0x0a, 0x03, 0x41, 0x2e, 0x42, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x50, + 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x42, 0x09, 0x9a, 0x4a, 0x06, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x3a, 0x6d, 0x9a, 0x4a, 0x6a, 0x0a, 0x3c, 0x0a, 0x03, 0x72, 0x65, 0x73, + 0x72, 0x35, 0x0a, 0x18, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2f, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0a, 0x0a, 0x02, + 0x69, 0x64, 0x12, 0x04, 0x24, 0x2e, 0x69, 0x64, 0x1a, 0x03, 0x31, 0x30, 0x73, 0x22, 0x08, 0x0a, + 0x06, 0x0a, 0x02, 0x32, 0x73, 0x10, 0x03, 0x0a, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, + 0x01, 0x5a, 0x08, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x0a, 0x16, 0x0a, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x6a, 0x0e, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x06, 0x1a, 0x04, 0x70, + 0x6f, 0x73, 0x74, 0x22, 0xc8, 0x04, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x26, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, + 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x41, 0x48, 0x00, 0x52, 0x05, 0x61, 0x74, 0x74, + 0x72, 0x41, 0x12, 0x26, 0x0a, 0x01, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x41, 0x48, 0x00, 0x52, 0x05, 0x61, 0x74, 0x74, 0x72, 0x41, 0x12, 0x26, - 0x0a, 0x01, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x66, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, - 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x50, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x2f, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x72, - 0x41, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x66, 0x6f, 0x6f, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x41, 0x1a, 0x2f, 0x0a, 0x05, 0x41, 0x74, 0x74, - 0x72, 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x03, 0x62, 0x61, 0x72, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x42, 0x3a, 0xa5, 0x01, 0x9a, 0x4a, 0xa1, - 0x01, 0x0a, 0x8a, 0x01, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x82, 0x01, 0x0a, 0x18, 0x75, 0x73, - 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0f, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x09, 0x24, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x27, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, - 0x79, 0x70, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x27, 0x49, 0x54, 0x45, 0x4d, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x27, 0x29, 0x1a, 0x03, 0x32, 0x30, 0x73, 0x22, 0x1f, 0x12, - 0x1d, 0x0a, 0x02, 0x31, 0x73, 0x11, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x3f, 0x19, 0x33, - 0x33, 0x33, 0x33, 0x33, 0x33, 0xfb, 0x3f, 0x22, 0x03, 0x33, 0x30, 0x73, 0x28, 0x03, 0x0a, 0x12, - 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x5a, 0x08, 0x72, 0x65, 0x73, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x8d, 0x05, 0x0a, 0x04, 0x49, - 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x35, 0x0a, 0x08, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, - 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x1a, 0xf1, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, 0x12, 0x38, 0x0a, 0x06, - 0x61, 0x64, 0x64, 0x72, 0x5f, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x66, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x41, 0x48, 0x00, 0x52, - 0x05, 0x61, 0x64, 0x64, 0x72, 0x41, 0x12, 0x2f, 0x0a, 0x01, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, - 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x41, - 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, - 0x6f, 0x6f, 0x3a, 0x1d, 0x9a, 0x4a, 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x50, 0x0a, 0x0c, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, + 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x2f, 0x0a, 0x05, + 0x41, 0x74, 0x74, 0x72, 0x41, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x41, 0x1a, 0x2f, 0x0a, + 0x05, 0x41, 0x74, 0x74, 0x72, 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x14, 0x9a, 0x4a, 0x11, 0x1a, 0x0f, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x42, 0x3a, 0xa5, + 0x01, 0x9a, 0x4a, 0xa1, 0x01, 0x0a, 0x8a, 0x01, 0x0a, 0x03, 0x72, 0x65, 0x73, 0x72, 0x82, 0x01, + 0x0a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0f, 0x0a, 0x02, 0x69, 0x64, + 0x12, 0x09, 0x24, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x27, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, + 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x27, 0x49, + 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x27, 0x29, 0x1a, 0x03, 0x32, 0x30, + 0x73, 0x22, 0x1f, 0x12, 0x1d, 0x0a, 0x02, 0x31, 0x73, 0x11, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0xe6, 0x3f, 0x19, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xfb, 0x3f, 0x22, 0x03, 0x33, 0x30, 0x73, + 0x28, 0x03, 0x0a, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x5a, 0x08, 0x72, 0x65, + 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x8d, + 0x05, 0x0a, 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xf1, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, + 0x64, 0x72, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x32, + 0x12, 0x38, 0x0a, 0x06, 0x61, 0x64, 0x64, 0x72, 0x5f, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, - 0x41, 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x42, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x1d, 0x9a, 0x4a, - 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x22, 0x38, 0x0a, 0x0c, 0x4c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x4c, - 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x30, 0x10, 0x00, - 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x31, 0x10, 0x01, 0x3a, 0x17, 0x9a, 0x4a, 0x14, 0x1a, 0x12, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, - 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x33, 0x22, 0x71, 0x0a, 0x08, 0x49, 0x74, 0x65, 0x6d, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, - 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, - 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x32, 0x10, 0x02, - 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x33, 0x10, - 0x03, 0x1a, 0x17, 0x9a, 0x4a, 0x14, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, - 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x0e, 0x9a, 0x4a, 0x0b, 0x1a, - 0x09, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x32, 0x5e, 0x0a, 0x11, 0x46, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x44, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x66, 0x65, 0x64, + 0x41, 0x48, 0x00, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x41, 0x12, 0x2f, 0x0a, 0x01, 0x62, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x48, 0x00, 0x52, 0x01, 0x62, 0x1a, 0x38, 0x0a, 0x05, 0x41, + 0x64, 0x64, 0x72, 0x41, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x3a, 0x1d, 0x9a, 0x4a, 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, + 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x41, 0x64, 0x64, 0x72, 0x41, 0x1a, 0x38, 0x0a, 0x05, 0x41, 0x64, 0x64, 0x72, 0x42, 0x12, 0x10, + 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x62, 0x61, 0x72, + 0x3a, 0x1d, 0x9a, 0x4a, 0x1a, 0x1a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, + 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x42, 0x22, + 0x38, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x30, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x3a, 0x17, 0x9a, 0x4a, 0x14, 0x1a, 0x12, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x33, 0x22, 0x71, 0x0a, 0x08, 0x49, + 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x54, 0x45, 0x4d, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x33, 0x10, 0x03, 0x1a, 0x17, 0x9a, 0x4a, 0x14, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x0e, + 0x9a, 0x4a, 0x0b, 0x1a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x32, 0x5e, + 0x0a, 0x11, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1a, + 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x1a, 0x03, 0x9a, 0x4a, 0x00, 0x42, 0xad, 0x01, 0x9a, 0x4a, 0x22, - 0x12, 0x0f, 0x70, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x42, 0x0f, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x1d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x66, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x46, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x0a, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x16, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, - 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x1a, 0x03, 0x9a, 0x4a, 0x00, 0x42, 0xad, + 0x01, 0x9a, 0x4a, 0x22, 0x12, 0x0f, 0x70, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0f, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x1d, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x66, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, + 0x0a, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x0a, 0x46, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x16, 0x46, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0a, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/_examples/02_simple/federation/federation_grpc_federation.pb.go b/_examples/02_simple/federation/federation_grpc_federation.pb.go index b387f1fd..0373cd6f 100644 --- a/_examples/02_simple/federation/federation_grpc_federation.pb.go +++ b/_examples/02_simple/federation/federation_grpc_federation.pb.go @@ -1617,10 +1617,10 @@ func (s *FederationService) resolve_Federation_GetPostResponse(ctx context.Conte grpcfed.RecordErrorToSpan(ctx, err) return nil, err } - // (grpc.federation.field).by = "url.user().username()" + // (grpc.federation.field).by = "url.userinfo().username()" if err := grpcfed.SetCELValue(ctx, &grpcfed.SetCELValueParam[string]{ Value: value, - Expr: `url.user().username()`, + Expr: `url.userinfo().username()`, CacheIndex: 59, Setter: func(v string) error { ret.UrlUserName = v diff --git a/_examples/02_simple/proto/federation/federation.proto b/_examples/02_simple/proto/federation/federation.proto index 98ab0fb3..cc6b7c20 100644 --- a/_examples/02_simple/proto/federation/federation.proto +++ b/_examples/02_simple/proto/federation/federation.proto @@ -79,7 +79,7 @@ message GetPostResponse { google.protobuf.Timestamp null_timestamp3 = 30 [(grpc.federation.field).by = "true ? null : google.protobuf.Timestamp{}"]; string jp_loc = 31 [(grpc.federation.field).by = "jp_time.location().string()"]; string strings_join = 32 [(grpc.federation.field).by = "strings_join"]; - string url_user_name = 33 [(grpc.federation.field).by = "url.user().username()"]; + string url_user_name = 33 [(grpc.federation.field).by = "url.userinfo().username()"]; } message A { diff --git a/grpc/federation/cel/url_test.go b/grpc/federation/cel/url_test.go index 809c2ba9..134cf982 100644 --- a/grpc/federation/cel/url_test.go +++ b/grpc/federation/cel/url_test.go @@ -276,17 +276,13 @@ func TestURLFunctions(t *testing.T) { name: "parse force query", expr: `grpc.federation.url.parse('https://example.com/path?').forceQuery()`, cmp: func(got ref.Val) error { - gotV, ok := got.(types.String) - if !ok { - return fmt.Errorf("invalid result type: %T", got) - } + gotV := got.(types.Bool) parse, err := url.Parse("https://example.com/path?") if err != nil { return err } - parse.ForceQuery = true - expected := parse.String() - if diff := cmp.Diff(string(gotV), expected); diff != "" { + expected := parse.ForceQuery + if diff := cmp.Diff(bool(gotV), expected); diff != "" { return fmt.Errorf("(-got, +want)\n%s", diff) } return nil From 2ce32a66ce3b03996cd79ce65f146cbfd3a94888 Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Tue, 1 Oct 2024 17:11:26 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=F0=9F=8E=A8=20removed=20unnecessary=20er?= =?UTF-8?q?ror=20return?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grpc/federation/cel/url.go | 193 +++++++++----------------------- grpc/federation/cel/url_test.go | 45 ++------ 2 files changed, 59 insertions(+), 179 deletions(-) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index de351295..c7c63cf8 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -17,20 +17,11 @@ var ( UserinfoType = cel.ObjectType("grpc.federation.url.Userinfo") ) -func (x *URL) GoURL() (url.URL, error) { - var user *url.Userinfo - if u := x.GetUser(); u != nil { - if u2, err := u.GoUserinfo(); err != nil { - return url.URL{}, err - } else { - user = u2 - } - } - +func (x *URL) GoURL() url.URL { return url.URL{ Scheme: x.GetScheme(), Opaque: x.GetOpaque(), - User: user, + User: x.GetUser().GoUserinfo(), Host: x.GetHost(), Path: x.GetPath(), RawPath: x.GetRawPath(), @@ -39,17 +30,17 @@ func (x *URL) GoURL() (url.URL, error) { RawQuery: x.GetRawQuery(), Fragment: x.GetFragment(), RawFragment: x.GetRawFragment(), - }, nil + } } -func (x *Userinfo) GoUserinfo() (*url.Userinfo, error) { +func (x *Userinfo) GoUserinfo() *url.Userinfo { if x == nil { - return nil, nil + return nil } if x.GetPasswordSet() { - return url.UserPassword(x.GetUsername(), x.GetPassword()), nil + return url.UserPassword(x.GetUsername(), x.GetPassword()) } - return url.User(x.GetUsername()), nil + return url.User(x.GetUsername()) } var _ cel.SingletonLibrary = new(URLLibrary) @@ -76,7 +67,7 @@ func createURLID(name string) string { return createID(URLPackageName, name) } -func (lib *URLLibrary) refToGoURLValue(v ref.Val) (url.URL, error) { +func (lib *URLLibrary) refToGoURLValue(v ref.Val) url.URL { return v.Value().(*URL).GoURL() } @@ -92,15 +83,17 @@ func (lib *URLLibrary) toURLValue(v url.URL) ref.Val { } return lib.typeAdapter.NativeToValue(&URL{ - Scheme: v.Scheme, - Opaque: v.Opaque, - User: userinfo, - Host: v.Host, - Path: v.Path, - RawPath: v.RawPath, - ForceQuery: v.ForceQuery, - RawQuery: v.RawQuery, - Fragment: v.Fragment, + Scheme: v.Scheme, + Opaque: v.Opaque, + User: userinfo, + Host: v.Host, + Path: v.Path, + RawPath: v.RawPath, + OmitHost: v.OmitHost, + ForceQuery: v.ForceQuery, + RawQuery: v.RawQuery, + Fragment: v.Fragment, + RawFragment: v.RawFragment, }) } @@ -202,10 +195,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "scheme", MemberOverloadFunc(createURLID("scheme_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := lib.refToGoURLValue(self) - if err != nil { - return types.NewErr(err.Error()) - } + v := lib.refToGoURLValue(self) return types.String(v.Scheme) }, ), @@ -214,10 +204,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "opaque", MemberOverloadFunc(createURLID("opaque_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Opaque) }, ), @@ -226,10 +213,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "userinfo", // user is not a valid field name MemberOverloadFunc(createURLID("user_url_userinfo"), URLType, []*cel.Type{}, UserinfoType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() password, hasPassword := v.User.Password() return lib.toUserinfoValue(v.User.Username(), password, hasPassword) }, @@ -239,10 +223,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "host", MemberOverloadFunc(createURLID("host_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Host) }, ), @@ -251,10 +232,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "path", MemberOverloadFunc(createURLID("path_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Path) }, ), @@ -263,10 +241,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "rawPath", MemberOverloadFunc(createURLID("rawPath_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.RawPath) }, ), @@ -275,22 +250,16 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "omitHost", MemberOverloadFunc(createURLID("omitHost_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.Bool(v.OmitHost) }, ), ), BindMemberFunction( "forceQuery", - MemberOverloadFunc(createURLID("forceQuery_url_string"), URLType, []*cel.Type{}, cel.BoolType, + MemberOverloadFunc(createURLID("forceQuery_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.Bool(v.ForceQuery) }, ), @@ -299,10 +268,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "rawQuery", MemberOverloadFunc(createURLID("rawQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.RawQuery) }, ), @@ -311,10 +277,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "fragment", MemberOverloadFunc(createURLID("fragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Fragment) }, ), @@ -323,10 +286,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "rawFragment", MemberOverloadFunc(createURLID("rawFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.RawFragment) }, ), @@ -335,10 +295,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "escapedFragment", MemberOverloadFunc(createURLID("escapedFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.EscapedFragment()) }, ), @@ -347,10 +304,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "escapedPath", MemberOverloadFunc(createURLID("escapedPath_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.EscapedPath()) }, ), @@ -359,10 +313,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "hostname", MemberOverloadFunc(createURLID("hostname_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Hostname()) }, ), @@ -371,10 +322,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "isAbs", MemberOverloadFunc(createURLID("isAbs_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.Bool(v.IsAbs()) }, ), @@ -383,10 +331,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "joinPath", MemberOverloadFunc(createURLID("joinPath_url_strings_url"), URLType, []*cel.Type{cel.ListType(cel.StringType)}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() elems := args[0].(traits.Lister) var paths []string @@ -395,6 +340,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { paths = append(paths, string(pathElem.(types.String))) } + var err error v.Path, err = url.JoinPath(v.Path, paths...) if err != nil { return types.NewErr(err.Error()) @@ -408,10 +354,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "marshalBinary", MemberOverloadFunc(createURLID("MarshalBinary_url_bytes"), URLType, []*cel.Type{}, cel.BytesType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() b, err := v.MarshalBinary() if err != nil { @@ -426,10 +369,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "parse", MemberOverloadFunc(createURLID("parse_url_string_url"), URLType, []*cel.Type{cel.StringType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() u, err := v.Parse(string(args[0].(types.String))) if err != nil { @@ -444,10 +384,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "port", MemberOverloadFunc(createURLID("port_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Port()) }, ), @@ -457,10 +394,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "query", MemberOverloadFunc(createURLID("query_url_map"), URLType, []*cel.Type{}, cel.MapType(cel.StringType, cel.ListType(cel.StringType)), func(ctx context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() adapter := types.DefaultTypeAdapter queryParams := v.Query() @@ -477,10 +411,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "redacted", MemberOverloadFunc(createURLID("redacted_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.Redacted()) }, ), @@ -489,10 +420,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "requestURI", MemberOverloadFunc(createURLID("requestURI_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.RequestURI()) }, ), @@ -501,15 +429,9 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "resolveReference", MemberOverloadFunc(createURLID("resolveReference_url_url_url"), URLType, []*cel.Type{URLType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() - r, err := args[0].Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + r := args[0].Value().(*URL).GoURL() u := v.ResolveReference(&r) return lib.toURLValue(*u) @@ -520,10 +442,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "string", MemberOverloadFunc(createURLID("string_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*URL).GoURL() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*URL).GoURL() return types.String(v.String()) }, ), @@ -563,10 +482,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "username", MemberOverloadFunc(createURLID("username_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*Userinfo).GoUserinfo() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*Userinfo).GoUserinfo() return types.String(v.Username()) }, ), @@ -575,10 +491,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "password", MemberOverloadFunc(createURLID("password_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*Userinfo).GoUserinfo() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*Userinfo).GoUserinfo() password, _ := v.Password() return types.String(password) }, @@ -588,10 +501,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "passwordSet", MemberOverloadFunc(createURLID("passwordSet_userinfo_bool"), UserinfoType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*Userinfo).GoUserinfo() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*Userinfo).GoUserinfo() _, hasPassword := v.Password() return types.Bool(hasPassword) }, @@ -601,10 +511,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "string", MemberOverloadFunc(createURLID("string_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v, err := self.Value().(*Userinfo).GoUserinfo() - if err != nil { - return types.NewErr(err.Error()) - } + v := self.Value().(*Userinfo).GoUserinfo() return types.String(v.String()) }, ), diff --git a/grpc/federation/cel/url_test.go b/grpc/federation/cel/url_test.go index 134cf982..a4554140 100644 --- a/grpc/federation/cel/url_test.go +++ b/grpc/federation/cel/url_test.go @@ -118,10 +118,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotURL, err := gotV.GoURL() - if err != nil { - return err - } + gotURL := gotV.GoURL() expected, err := url.Parse("https://example.com/path?query=1#fragment") if err != nil { return err @@ -140,10 +137,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotURL, err := gotV.GoURL() - if err != nil { - return err - } + gotURL := gotV.GoURL() expected, err := url.ParseRequestURI("https://example.com/path?query=1#fragment") if err != nil { return err @@ -200,10 +194,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotUser, err := gotV.GoUserinfo() - if err != nil { - return err - } + gotUser := gotV.GoUserinfo() parse, err := url.Parse("https://example.com/path?query=1#fragment") if err != nil { return err @@ -429,10 +420,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotURL, err := gotV.GoURL() - if err != nil { - return err - } + gotURL := gotV.GoURL() parse, err := url.Parse("https://example.com/path?query=1#fragment") if err != nil { return err @@ -474,10 +462,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotURL, err := gotV.GoURL() - if err != nil { - return err - } + gotURL := gotV.GoURL() parse, err := url.Parse("https://example.com/path?query=1#fragment") if err != nil { return err @@ -591,10 +576,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotURL, err := gotV.GoURL() - if err != nil { - return err - } + gotURL := gotV.GoURL() parse, err := url.Parse("https://example.com/path?query=1#fragment") if err != nil { return err @@ -637,10 +619,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotURL, err := gotV.GoURL() - if err != nil { - return err - } + gotURL := gotV.GoURL() parse, err := url.Parse("https://example.com/path?query=1#fragment") if err != nil { return err @@ -662,10 +641,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotUser, err := gotV.GoUserinfo() - if err != nil { - return err - } + gotUser := gotV.GoUserinfo() expected := url.User("username") if diff := userinfoDiff(gotUser, expected); diff != "" { return fmt.Errorf("(-got, +want)\n%s", diff) @@ -681,10 +657,7 @@ func TestURLFunctions(t *testing.T) { if !ok { return fmt.Errorf("invalid result type: %T", got) } - gotUser, err := gotV.GoUserinfo() - if err != nil { - return err - } + gotUser := gotV.GoUserinfo() expected := url.UserPassword("username", "password") if diff := userinfoDiff(gotUser, expected); diff != "" { return fmt.Errorf("(-got, +want)\n%s", diff) From 38a3d883969b6b12a412dbefe53c50c2ecb7a47b Mon Sep 17 00:00:00 2001 From: pikachu0310 Date: Tue, 1 Oct 2024 19:10:54 +0900 Subject: [PATCH 12/12] =?UTF-8?q?=F0=9F=8E=A8=20URL=20handling=20to=20use?= =?UTF-8?q?=20lib.refToGoURLValue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also lib.refToGoUserinfoValue --- grpc/federation/cel/url.go | 58 ++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/grpc/federation/cel/url.go b/grpc/federation/cel/url.go index c7c63cf8..fe3f14b5 100644 --- a/grpc/federation/cel/url.go +++ b/grpc/federation/cel/url.go @@ -71,6 +71,10 @@ func (lib *URLLibrary) refToGoURLValue(v ref.Val) url.URL { return v.Value().(*URL).GoURL() } +func (lib *URLLibrary) refToGoUserinfoValue(v ref.Val) *url.Userinfo { + return v.Value().(*Userinfo).GoUserinfo() +} + func (lib *URLLibrary) toURLValue(v url.URL) ref.Val { var userinfo *Userinfo if v.User != nil { @@ -204,7 +208,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "opaque", MemberOverloadFunc(createURLID("opaque_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Opaque) }, ), @@ -213,7 +217,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "userinfo", // user is not a valid field name MemberOverloadFunc(createURLID("user_url_userinfo"), URLType, []*cel.Type{}, UserinfoType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) password, hasPassword := v.User.Password() return lib.toUserinfoValue(v.User.Username(), password, hasPassword) }, @@ -223,7 +227,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "host", MemberOverloadFunc(createURLID("host_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Host) }, ), @@ -232,7 +236,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "path", MemberOverloadFunc(createURLID("path_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Path) }, ), @@ -241,7 +245,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "rawPath", MemberOverloadFunc(createURLID("rawPath_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.RawPath) }, ), @@ -250,7 +254,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "omitHost", MemberOverloadFunc(createURLID("omitHost_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.Bool(v.OmitHost) }, ), @@ -259,7 +263,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "forceQuery", MemberOverloadFunc(createURLID("forceQuery_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.Bool(v.ForceQuery) }, ), @@ -268,7 +272,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "rawQuery", MemberOverloadFunc(createURLID("rawQuery_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.RawQuery) }, ), @@ -277,7 +281,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "fragment", MemberOverloadFunc(createURLID("fragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Fragment) }, ), @@ -286,7 +290,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "rawFragment", MemberOverloadFunc(createURLID("rawFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.RawFragment) }, ), @@ -295,7 +299,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "escapedFragment", MemberOverloadFunc(createURLID("escapedFragment_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.EscapedFragment()) }, ), @@ -304,7 +308,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "escapedPath", MemberOverloadFunc(createURLID("escapedPath_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.EscapedPath()) }, ), @@ -313,7 +317,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "hostname", MemberOverloadFunc(createURLID("hostname_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Hostname()) }, ), @@ -322,7 +326,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "isAbs", MemberOverloadFunc(createURLID("isAbs_url_bool"), URLType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.Bool(v.IsAbs()) }, ), @@ -331,7 +335,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "joinPath", MemberOverloadFunc(createURLID("joinPath_url_strings_url"), URLType, []*cel.Type{cel.ListType(cel.StringType)}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) elems := args[0].(traits.Lister) var paths []string @@ -354,7 +358,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "marshalBinary", MemberOverloadFunc(createURLID("MarshalBinary_url_bytes"), URLType, []*cel.Type{}, cel.BytesType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) b, err := v.MarshalBinary() if err != nil { @@ -369,7 +373,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "parse", MemberOverloadFunc(createURLID("parse_url_string_url"), URLType, []*cel.Type{cel.StringType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) u, err := v.Parse(string(args[0].(types.String))) if err != nil { @@ -384,7 +388,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "port", MemberOverloadFunc(createURLID("port_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Port()) }, ), @@ -394,7 +398,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "query", MemberOverloadFunc(createURLID("query_url_map"), URLType, []*cel.Type{}, cel.MapType(cel.StringType, cel.ListType(cel.StringType)), func(ctx context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) adapter := types.DefaultTypeAdapter queryParams := v.Query() @@ -411,7 +415,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "redacted", MemberOverloadFunc(createURLID("redacted_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.Redacted()) }, ), @@ -420,7 +424,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "requestURI", MemberOverloadFunc(createURLID("requestURI_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.RequestURI()) }, ), @@ -429,7 +433,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "resolveReference", MemberOverloadFunc(createURLID("resolveReference_url_url_url"), URLType, []*cel.Type{URLType}, URLType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) r := args[0].Value().(*URL).GoURL() u := v.ResolveReference(&r) @@ -442,7 +446,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "string", MemberOverloadFunc(createURLID("string_url_string"), URLType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*URL).GoURL() + v := lib.refToGoURLValue(self) return types.String(v.String()) }, ), @@ -482,7 +486,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "username", MemberOverloadFunc(createURLID("username_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*Userinfo).GoUserinfo() + v := lib.refToGoUserinfoValue(self) return types.String(v.Username()) }, ), @@ -491,7 +495,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "password", MemberOverloadFunc(createURLID("password_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*Userinfo).GoUserinfo() + v := lib.refToGoUserinfoValue(self) password, _ := v.Password() return types.String(password) }, @@ -501,7 +505,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "passwordSet", MemberOverloadFunc(createURLID("passwordSet_userinfo_bool"), UserinfoType, []*cel.Type{}, cel.BoolType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*Userinfo).GoUserinfo() + v := lib.refToGoUserinfoValue(self) _, hasPassword := v.Password() return types.Bool(hasPassword) }, @@ -511,7 +515,7 @@ func (lib *URLLibrary) CompileOptions() []cel.EnvOption { "string", MemberOverloadFunc(createURLID("string_userinfo_string"), UserinfoType, []*cel.Type{}, cel.StringType, func(_ context.Context, self ref.Val, args ...ref.Val) ref.Val { - v := self.Value().(*Userinfo).GoUserinfo() + v := lib.refToGoUserinfoValue(self) return types.String(v.String()) }, ),