From acece7bd06d375683cba603f78d2c57cd63ef118 Mon Sep 17 00:00:00 2001 From: worstell Date: Fri, 3 May 2024 21:00:13 -0400 Subject: [PATCH] feat: refactor type registry (#1403) - separate go-runtime/typeregistry and internal schema/typeregistry; add schema type lookups for ingress encoding - fixes for deriving schema types for sum type variants --- .../xyz/block/ftl/v1/schema/schema.pb.go | 523 ++++++++++++------ .../xyz/block/ftl/v1/schema/schema.proto | 9 + backend/schema/protobuf.go | 5 +- backend/schema/type_registry.go | 71 +++ backend/schema/visit.go | 6 + buildengine/build_go_test.go | 53 +- buildengine/testdata/projects/other/other.go | 21 +- buildengine/testdata/type_registry_main.go | 72 +++ .../xyz/block/ftl/v1/schema/schema_pb.ts | 80 +++ .../build-template/_ftl.tmpl/go/main/main.go | 35 +- go-runtime/compile/build.go | 53 +- go-runtime/compile/schema.go | 118 +++- .../ftl/{ => typeregistry}/type_registry.go | 40 +- 13 files changed, 788 insertions(+), 298 deletions(-) create mode 100644 backend/schema/type_registry.go create mode 100644 buildengine/testdata/type_registry_main.go rename go-runtime/ftl/{ => typeregistry}/type_registry.go (58%) diff --git a/backend/protos/xyz/block/ftl/v1/schema/schema.pb.go b/backend/protos/xyz/block/ftl/v1/schema/schema.pb.go index d1795d4d11..abb13f227e 100644 --- a/backend/protos/xyz/block/ftl/v1/schema/schema.pb.go +++ b/backend/protos/xyz/block/ftl/v1/schema/schema.pb.go @@ -2252,6 +2252,53 @@ func (x *StringValue) GetValue() string { return "" } +type SumTypeVariants struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value []string `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"` +} + +func (x *SumTypeVariants) Reset() { + *x = SumTypeVariants{} + if protoimpl.UnsafeEnabled { + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SumTypeVariants) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SumTypeVariants) ProtoMessage() {} + +func (x *SumTypeVariants) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[34] + 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 SumTypeVariants.ProtoReflect.Descriptor instead. +func (*SumTypeVariants) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{34} +} + +func (x *SumTypeVariants) GetValue() []string { + if x != nil { + return x.Value + } + return nil +} + type Time struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2263,7 +2310,7 @@ type Time struct { func (x *Time) Reset() { *x = Time{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[34] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2276,7 +2323,7 @@ func (x *Time) String() string { func (*Time) ProtoMessage() {} func (x *Time) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[34] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2289,7 +2336,7 @@ func (x *Time) ProtoReflect() protoreflect.Message { // Deprecated: Use Time.ProtoReflect.Descriptor instead. func (*Time) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{34} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{35} } func (x *Time) GetPos() *Position { @@ -2324,7 +2371,7 @@ type Type struct { func (x *Type) Reset() { *x = Type{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2337,7 +2384,7 @@ func (x *Type) String() string { func (*Type) ProtoMessage() {} func (x *Type) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2350,7 +2397,7 @@ func (x *Type) ProtoReflect() protoreflect.Message { // Deprecated: Use Type.ProtoReflect.Descriptor instead. func (*Type) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{35} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{36} } func (m *Type) GetValue() isType_Value { @@ -2532,7 +2579,7 @@ type TypeParameter struct { func (x *TypeParameter) Reset() { *x = TypeParameter{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2545,7 +2592,7 @@ func (x *TypeParameter) String() string { func (*TypeParameter) ProtoMessage() {} func (x *TypeParameter) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2558,7 +2605,7 @@ func (x *TypeParameter) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeParameter.ProtoReflect.Descriptor instead. func (*TypeParameter) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{36} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{37} } func (x *TypeParameter) GetPos() *Position { @@ -2575,6 +2622,61 @@ func (x *TypeParameter) GetName() string { return "" } +type TypeRegistry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SchemaTypes map[string]*Type `protobuf:"bytes,1,rep,name=schemaTypes,proto3" json:"schemaTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + SumTypes map[string]*SumTypeVariants `protobuf:"bytes,2,rep,name=sumTypes,proto3" json:"sumTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *TypeRegistry) Reset() { + *x = TypeRegistry{} + if protoimpl.UnsafeEnabled { + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TypeRegistry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TypeRegistry) ProtoMessage() {} + +func (x *TypeRegistry) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[38] + 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 TypeRegistry.ProtoReflect.Descriptor instead. +func (*TypeRegistry) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{38} +} + +func (x *TypeRegistry) GetSchemaTypes() map[string]*Type { + if x != nil { + return x.SchemaTypes + } + return nil +} + +func (x *TypeRegistry) GetSumTypes() map[string]*SumTypeVariants { + if x != nil { + return x.SumTypes + } + return nil +} + type TypeValue struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2587,7 +2689,7 @@ type TypeValue struct { func (x *TypeValue) Reset() { *x = TypeValue{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[37] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2600,7 +2702,7 @@ func (x *TypeValue) String() string { func (*TypeValue) ProtoMessage() {} func (x *TypeValue) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[37] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2613,7 +2715,7 @@ func (x *TypeValue) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeValue.ProtoReflect.Descriptor instead. func (*TypeValue) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{37} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{39} } func (x *TypeValue) GetPos() *Position { @@ -2641,7 +2743,7 @@ type Unit struct { func (x *Unit) Reset() { *x = Unit{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[38] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2654,7 +2756,7 @@ func (x *Unit) String() string { func (*Unit) ProtoMessage() {} func (x *Unit) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[38] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2667,7 +2769,7 @@ func (x *Unit) ProtoReflect() protoreflect.Message { // Deprecated: Use Unit.ProtoReflect.Descriptor instead. func (*Unit) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{38} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{40} } func (x *Unit) GetPos() *Position { @@ -2693,7 +2795,7 @@ type Value struct { func (x *Value) Reset() { *x = Value{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2706,7 +2808,7 @@ func (x *Value) String() string { func (*Value) ProtoMessage() {} func (x *Value) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2719,7 +2821,7 @@ func (x *Value) ProtoReflect() protoreflect.Message { // Deprecated: Use Value.ProtoReflect.Descriptor instead. func (*Value) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{39} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{41} } func (m *Value) GetValue() isValue_Value { @@ -2790,7 +2892,7 @@ type Verb struct { func (x *Verb) Reset() { *x = Verb{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2803,7 +2905,7 @@ func (x *Verb) String() string { func (*Verb) ProtoMessage() {} func (x *Verb) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40] + mi := &file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2816,7 +2918,7 @@ func (x *Verb) ProtoReflect() protoreflect.Message { // Deprecated: Use Verb.ProtoReflect.Descriptor instead. func (*Verb) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{40} + return file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP(), []int{42} } func (x *Verb) GetRuntime() *VerbRuntime { @@ -3218,118 +3320,145 @@ var file_xyz_block_ftl_v1_schema_schema_proto_rawDesc = []byte{ 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0x48, 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, - 0x73, 0x22, 0x9a, 0x05, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x03, 0x69, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0x27, 0x0a, 0x0f, 0x53, 0x75, 0x6d, 0x54, 0x79, + 0x70, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x48, 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, + 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0x9a, 0x05, 0x0a, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x03, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, + 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x03, 0x69, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x48, 0x00, 0x52, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x39, 0x0a, + 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x48, 0x00, + 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x36, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x03, 0x69, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x05, - 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x79, - 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x48, 0x00, 0x52, 0x05, 0x66, - 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, - 0x36, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x61, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x12, 0x33, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, - 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, - 0x42, 0x6f, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x33, 0x0a, 0x04, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, - 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x12, 0x36, 0x0a, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x72, 0x72, 0x61, 0x79, - 0x48, 0x00, 0x52, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x12, 0x30, 0x0a, 0x03, 0x6d, 0x61, 0x70, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x03, 0x6d, 0x61, 0x70, 0x12, 0x30, 0x0a, 0x03, 0x61, - 0x6e, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x33, 0x0a, - 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, - 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x75, 0x6e, - 0x69, 0x74, 0x12, 0x30, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x48, 0x00, 0x52, + 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x72, 0x72, 0x61, 0x79, 0x48, 0x00, 0x52, 0x05, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x12, 0x30, 0x0a, 0x03, 0x6d, 0x61, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, - 0x03, 0x72, 0x65, 0x66, 0x12, 0x3f, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x65, - 0x0a, 0x0d, 0x54, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, - 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x06, 0x0a, - 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0x82, 0x01, 0x0a, 0x09, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0x48, 0x0a, 0x04, 0x55, 0x6e, - 0x69, 0x74, 0x12, 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, + 0x03, 0x6d, 0x61, 0x70, 0x12, 0x30, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x6e, 0x79, 0x48, + 0x00, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x33, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x55, + 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x30, 0x0a, 0x03, 0x72, + 0x65, 0x66, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x3f, 0x0a, + 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, - 0x5f, 0x70, 0x6f, 0x73, 0x22, 0xdf, 0x01, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x48, - 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, + 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x07, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x65, 0x0a, 0x0d, 0x54, 0x79, 0x70, 0x65, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, + 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0xff, + 0x02, 0x0a, 0x0c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, + 0x58, 0x0a, 0x0b, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x08, 0x73, 0x75, 0x6d, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x53, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x73, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x1a, 0x5d, 0x0a, 0x10, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x65, 0x0a, 0x0d, 0x53, 0x75, 0x6d, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3e, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x82, 0x01, 0x0a, 0x09, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, + 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, + 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0x0a, + 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, 0x48, 0x0a, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x38, 0x0a, + 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, - 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x74, 0x79, 0x70, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x48, 0x00, 0x52, 0x09, 0x74, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x96, 0x03, 0x0a, 0x04, 0x56, 0x65, 0x72, 0x62, 0x12, - 0x45, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x92, 0xf7, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x56, 0x65, 0x72, - 0x62, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, - 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x39, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x22, + 0xdf, 0x01, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x0a, 0x0a, 0x08, 0x5f, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x42, - 0x4e, 0x50, 0x01, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, - 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, - 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3b, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x70, 0x62, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x96, 0x03, 0x0a, 0x04, 0x56, 0x65, 0x72, 0x62, 0x12, 0x45, 0x0a, 0x07, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x92, 0xf7, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x56, 0x65, 0x72, 0x62, 0x52, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, + 0x01, 0x12, 0x38, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x01, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x08, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x70, 0x6f, 0x73, 0x42, 0x4e, 0x50, 0x01, 0x5a, 0x4a, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, + 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x3b, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -3344,7 +3473,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_rawDescGZIP() []byte { return file_xyz_block_ftl_v1_schema_schema_proto_rawDescData } -var file_xyz_block_ftl_v1_schema_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_xyz_block_ftl_v1_schema_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 45) var file_xyz_block_ftl_v1_schema_schema_proto_goTypes = []interface{}{ (*Any)(nil), // 0: xyz.block.ftl.v1.schema.Any (*Array)(nil), // 1: xyz.block.ftl.v1.schema.Array @@ -3380,44 +3509,48 @@ var file_xyz_block_ftl_v1_schema_schema_proto_goTypes = []interface{}{ (*Secret)(nil), // 31: xyz.block.ftl.v1.schema.Secret (*String)(nil), // 32: xyz.block.ftl.v1.schema.String (*StringValue)(nil), // 33: xyz.block.ftl.v1.schema.StringValue - (*Time)(nil), // 34: xyz.block.ftl.v1.schema.Time - (*Type)(nil), // 35: xyz.block.ftl.v1.schema.Type - (*TypeParameter)(nil), // 36: xyz.block.ftl.v1.schema.TypeParameter - (*TypeValue)(nil), // 37: xyz.block.ftl.v1.schema.TypeValue - (*Unit)(nil), // 38: xyz.block.ftl.v1.schema.Unit - (*Value)(nil), // 39: xyz.block.ftl.v1.schema.Value - (*Verb)(nil), // 40: xyz.block.ftl.v1.schema.Verb - (*ModuleRuntime)(nil), // 41: xyz.block.ftl.v1.schema.ModuleRuntime - (*VerbRuntime)(nil), // 42: xyz.block.ftl.v1.schema.VerbRuntime + (*SumTypeVariants)(nil), // 34: xyz.block.ftl.v1.schema.SumTypeVariants + (*Time)(nil), // 35: xyz.block.ftl.v1.schema.Time + (*Type)(nil), // 36: xyz.block.ftl.v1.schema.Type + (*TypeParameter)(nil), // 37: xyz.block.ftl.v1.schema.TypeParameter + (*TypeRegistry)(nil), // 38: xyz.block.ftl.v1.schema.TypeRegistry + (*TypeValue)(nil), // 39: xyz.block.ftl.v1.schema.TypeValue + (*Unit)(nil), // 40: xyz.block.ftl.v1.schema.Unit + (*Value)(nil), // 41: xyz.block.ftl.v1.schema.Value + (*Verb)(nil), // 42: xyz.block.ftl.v1.schema.Verb + nil, // 43: xyz.block.ftl.v1.schema.TypeRegistry.SchemaTypesEntry + nil, // 44: xyz.block.ftl.v1.schema.TypeRegistry.SumTypesEntry + (*ModuleRuntime)(nil), // 45: xyz.block.ftl.v1.schema.ModuleRuntime + (*VerbRuntime)(nil), // 46: xyz.block.ftl.v1.schema.VerbRuntime } var file_xyz_block_ftl_v1_schema_schema_proto_depIdxs = []int32{ 28, // 0: xyz.block.ftl.v1.schema.Any.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 1: xyz.block.ftl.v1.schema.Array.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 2: xyz.block.ftl.v1.schema.Array.element:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 2: xyz.block.ftl.v1.schema.Array.element:type_name -> xyz.block.ftl.v1.schema.Type 28, // 3: xyz.block.ftl.v1.schema.Bool.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 4: xyz.block.ftl.v1.schema.Bytes.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 5: xyz.block.ftl.v1.schema.Config.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 6: xyz.block.ftl.v1.schema.Config.type:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 6: xyz.block.ftl.v1.schema.Config.type:type_name -> xyz.block.ftl.v1.schema.Type 28, // 7: xyz.block.ftl.v1.schema.Data.pos:type_name -> xyz.block.ftl.v1.schema.Position - 36, // 8: xyz.block.ftl.v1.schema.Data.typeParameters:type_name -> xyz.block.ftl.v1.schema.TypeParameter + 37, // 8: xyz.block.ftl.v1.schema.Data.typeParameters:type_name -> xyz.block.ftl.v1.schema.TypeParameter 12, // 9: xyz.block.ftl.v1.schema.Data.fields:type_name -> xyz.block.ftl.v1.schema.Field 20, // 10: xyz.block.ftl.v1.schema.Data.metadata:type_name -> xyz.block.ftl.v1.schema.Metadata 28, // 11: xyz.block.ftl.v1.schema.Database.pos:type_name -> xyz.block.ftl.v1.schema.Position 5, // 12: xyz.block.ftl.v1.schema.Decl.data:type_name -> xyz.block.ftl.v1.schema.Data - 40, // 13: xyz.block.ftl.v1.schema.Decl.verb:type_name -> xyz.block.ftl.v1.schema.Verb + 42, // 13: xyz.block.ftl.v1.schema.Decl.verb:type_name -> xyz.block.ftl.v1.schema.Verb 6, // 14: xyz.block.ftl.v1.schema.Decl.database:type_name -> xyz.block.ftl.v1.schema.Database 8, // 15: xyz.block.ftl.v1.schema.Decl.enum:type_name -> xyz.block.ftl.v1.schema.Enum 4, // 16: xyz.block.ftl.v1.schema.Decl.config:type_name -> xyz.block.ftl.v1.schema.Config 31, // 17: xyz.block.ftl.v1.schema.Decl.secret:type_name -> xyz.block.ftl.v1.schema.Secret 28, // 18: xyz.block.ftl.v1.schema.Enum.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 19: xyz.block.ftl.v1.schema.Enum.type:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 19: xyz.block.ftl.v1.schema.Enum.type:type_name -> xyz.block.ftl.v1.schema.Type 9, // 20: xyz.block.ftl.v1.schema.Enum.variants:type_name -> xyz.block.ftl.v1.schema.EnumVariant 28, // 21: xyz.block.ftl.v1.schema.EnumVariant.pos:type_name -> xyz.block.ftl.v1.schema.Position - 39, // 22: xyz.block.ftl.v1.schema.EnumVariant.value:type_name -> xyz.block.ftl.v1.schema.Value + 41, // 22: xyz.block.ftl.v1.schema.EnumVariant.value:type_name -> xyz.block.ftl.v1.schema.Value 28, // 23: xyz.block.ftl.v1.schema.Error.pos:type_name -> xyz.block.ftl.v1.schema.Position 10, // 24: xyz.block.ftl.v1.schema.ErrorList.errors:type_name -> xyz.block.ftl.v1.schema.Error 28, // 25: xyz.block.ftl.v1.schema.Field.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 26: xyz.block.ftl.v1.schema.Field.type:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 26: xyz.block.ftl.v1.schema.Field.type:type_name -> xyz.block.ftl.v1.schema.Type 20, // 27: xyz.block.ftl.v1.schema.Field.metadata:type_name -> xyz.block.ftl.v1.schema.Metadata 28, // 28: xyz.block.ftl.v1.schema.Float.pos:type_name -> xyz.block.ftl.v1.schema.Position 15, // 29: xyz.block.ftl.v1.schema.IngressPathComponent.ingressPathLiteral:type_name -> xyz.block.ftl.v1.schema.IngressPathLiteral @@ -3427,8 +3560,8 @@ var file_xyz_block_ftl_v1_schema_schema_proto_depIdxs = []int32{ 28, // 33: xyz.block.ftl.v1.schema.Int.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 34: xyz.block.ftl.v1.schema.IntValue.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 35: xyz.block.ftl.v1.schema.Map.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 36: xyz.block.ftl.v1.schema.Map.key:type_name -> xyz.block.ftl.v1.schema.Type - 35, // 37: xyz.block.ftl.v1.schema.Map.value:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 36: xyz.block.ftl.v1.schema.Map.key:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 37: xyz.block.ftl.v1.schema.Map.value:type_name -> xyz.block.ftl.v1.schema.Type 22, // 38: xyz.block.ftl.v1.schema.Metadata.calls:type_name -> xyz.block.ftl.v1.schema.MetadataCalls 25, // 39: xyz.block.ftl.v1.schema.Metadata.ingress:type_name -> xyz.block.ftl.v1.schema.MetadataIngress 23, // 40: xyz.block.ftl.v1.schema.Metadata.cronJob:type_name -> xyz.block.ftl.v1.schema.MetadataCronJob @@ -3442,17 +3575,17 @@ var file_xyz_block_ftl_v1_schema_schema_proto_depIdxs = []int32{ 29, // 48: xyz.block.ftl.v1.schema.MetadataDatabases.calls:type_name -> xyz.block.ftl.v1.schema.Ref 28, // 49: xyz.block.ftl.v1.schema.MetadataIngress.pos:type_name -> xyz.block.ftl.v1.schema.Position 14, // 50: xyz.block.ftl.v1.schema.MetadataIngress.path:type_name -> xyz.block.ftl.v1.schema.IngressPathComponent - 41, // 51: xyz.block.ftl.v1.schema.Module.runtime:type_name -> xyz.block.ftl.v1.schema.ModuleRuntime + 45, // 51: xyz.block.ftl.v1.schema.Module.runtime:type_name -> xyz.block.ftl.v1.schema.ModuleRuntime 28, // 52: xyz.block.ftl.v1.schema.Module.pos:type_name -> xyz.block.ftl.v1.schema.Position 7, // 53: xyz.block.ftl.v1.schema.Module.decls:type_name -> xyz.block.ftl.v1.schema.Decl 28, // 54: xyz.block.ftl.v1.schema.Optional.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 55: xyz.block.ftl.v1.schema.Optional.type:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 55: xyz.block.ftl.v1.schema.Optional.type:type_name -> xyz.block.ftl.v1.schema.Type 28, // 56: xyz.block.ftl.v1.schema.Ref.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 57: xyz.block.ftl.v1.schema.Ref.typeParameters:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 57: xyz.block.ftl.v1.schema.Ref.typeParameters:type_name -> xyz.block.ftl.v1.schema.Type 28, // 58: xyz.block.ftl.v1.schema.Schema.pos:type_name -> xyz.block.ftl.v1.schema.Position 26, // 59: xyz.block.ftl.v1.schema.Schema.modules:type_name -> xyz.block.ftl.v1.schema.Module 28, // 60: xyz.block.ftl.v1.schema.Secret.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 61: xyz.block.ftl.v1.schema.Secret.type:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 61: xyz.block.ftl.v1.schema.Secret.type:type_name -> xyz.block.ftl.v1.schema.Type 28, // 62: xyz.block.ftl.v1.schema.String.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 63: xyz.block.ftl.v1.schema.StringValue.pos:type_name -> xyz.block.ftl.v1.schema.Position 28, // 64: xyz.block.ftl.v1.schema.Time.pos:type_name -> xyz.block.ftl.v1.schema.Position @@ -3461,30 +3594,34 @@ var file_xyz_block_ftl_v1_schema_schema_proto_depIdxs = []int32{ 32, // 67: xyz.block.ftl.v1.schema.Type.string:type_name -> xyz.block.ftl.v1.schema.String 3, // 68: xyz.block.ftl.v1.schema.Type.bytes:type_name -> xyz.block.ftl.v1.schema.Bytes 2, // 69: xyz.block.ftl.v1.schema.Type.bool:type_name -> xyz.block.ftl.v1.schema.Bool - 34, // 70: xyz.block.ftl.v1.schema.Type.time:type_name -> xyz.block.ftl.v1.schema.Time + 35, // 70: xyz.block.ftl.v1.schema.Type.time:type_name -> xyz.block.ftl.v1.schema.Time 1, // 71: xyz.block.ftl.v1.schema.Type.array:type_name -> xyz.block.ftl.v1.schema.Array 19, // 72: xyz.block.ftl.v1.schema.Type.map:type_name -> xyz.block.ftl.v1.schema.Map 0, // 73: xyz.block.ftl.v1.schema.Type.any:type_name -> xyz.block.ftl.v1.schema.Any - 38, // 74: xyz.block.ftl.v1.schema.Type.unit:type_name -> xyz.block.ftl.v1.schema.Unit + 40, // 74: xyz.block.ftl.v1.schema.Type.unit:type_name -> xyz.block.ftl.v1.schema.Unit 29, // 75: xyz.block.ftl.v1.schema.Type.ref:type_name -> xyz.block.ftl.v1.schema.Ref 27, // 76: xyz.block.ftl.v1.schema.Type.optional:type_name -> xyz.block.ftl.v1.schema.Optional 28, // 77: xyz.block.ftl.v1.schema.TypeParameter.pos:type_name -> xyz.block.ftl.v1.schema.Position - 28, // 78: xyz.block.ftl.v1.schema.TypeValue.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 79: xyz.block.ftl.v1.schema.TypeValue.value:type_name -> xyz.block.ftl.v1.schema.Type - 28, // 80: xyz.block.ftl.v1.schema.Unit.pos:type_name -> xyz.block.ftl.v1.schema.Position - 33, // 81: xyz.block.ftl.v1.schema.Value.stringValue:type_name -> xyz.block.ftl.v1.schema.StringValue - 18, // 82: xyz.block.ftl.v1.schema.Value.intValue:type_name -> xyz.block.ftl.v1.schema.IntValue - 37, // 83: xyz.block.ftl.v1.schema.Value.typeValue:type_name -> xyz.block.ftl.v1.schema.TypeValue - 42, // 84: xyz.block.ftl.v1.schema.Verb.runtime:type_name -> xyz.block.ftl.v1.schema.VerbRuntime - 28, // 85: xyz.block.ftl.v1.schema.Verb.pos:type_name -> xyz.block.ftl.v1.schema.Position - 35, // 86: xyz.block.ftl.v1.schema.Verb.request:type_name -> xyz.block.ftl.v1.schema.Type - 35, // 87: xyz.block.ftl.v1.schema.Verb.response:type_name -> xyz.block.ftl.v1.schema.Type - 20, // 88: xyz.block.ftl.v1.schema.Verb.metadata:type_name -> xyz.block.ftl.v1.schema.Metadata - 89, // [89:89] is the sub-list for method output_type - 89, // [89:89] is the sub-list for method input_type - 89, // [89:89] is the sub-list for extension type_name - 89, // [89:89] is the sub-list for extension extendee - 0, // [0:89] is the sub-list for field type_name + 43, // 78: xyz.block.ftl.v1.schema.TypeRegistry.schemaTypes:type_name -> xyz.block.ftl.v1.schema.TypeRegistry.SchemaTypesEntry + 44, // 79: xyz.block.ftl.v1.schema.TypeRegistry.sumTypes:type_name -> xyz.block.ftl.v1.schema.TypeRegistry.SumTypesEntry + 28, // 80: xyz.block.ftl.v1.schema.TypeValue.pos:type_name -> xyz.block.ftl.v1.schema.Position + 36, // 81: xyz.block.ftl.v1.schema.TypeValue.value:type_name -> xyz.block.ftl.v1.schema.Type + 28, // 82: xyz.block.ftl.v1.schema.Unit.pos:type_name -> xyz.block.ftl.v1.schema.Position + 33, // 83: xyz.block.ftl.v1.schema.Value.stringValue:type_name -> xyz.block.ftl.v1.schema.StringValue + 18, // 84: xyz.block.ftl.v1.schema.Value.intValue:type_name -> xyz.block.ftl.v1.schema.IntValue + 39, // 85: xyz.block.ftl.v1.schema.Value.typeValue:type_name -> xyz.block.ftl.v1.schema.TypeValue + 46, // 86: xyz.block.ftl.v1.schema.Verb.runtime:type_name -> xyz.block.ftl.v1.schema.VerbRuntime + 28, // 87: xyz.block.ftl.v1.schema.Verb.pos:type_name -> xyz.block.ftl.v1.schema.Position + 36, // 88: xyz.block.ftl.v1.schema.Verb.request:type_name -> xyz.block.ftl.v1.schema.Type + 36, // 89: xyz.block.ftl.v1.schema.Verb.response:type_name -> xyz.block.ftl.v1.schema.Type + 20, // 90: xyz.block.ftl.v1.schema.Verb.metadata:type_name -> xyz.block.ftl.v1.schema.Metadata + 36, // 91: xyz.block.ftl.v1.schema.TypeRegistry.SchemaTypesEntry.value:type_name -> xyz.block.ftl.v1.schema.Type + 34, // 92: xyz.block.ftl.v1.schema.TypeRegistry.SumTypesEntry.value:type_name -> xyz.block.ftl.v1.schema.SumTypeVariants + 93, // [93:93] is the sub-list for method output_type + 93, // [93:93] is the sub-list for method input_type + 93, // [93:93] is the sub-list for extension type_name + 93, // [93:93] is the sub-list for extension extendee + 0, // [0:93] is the sub-list for field type_name } func init() { file_xyz_block_ftl_v1_schema_schema_proto_init() } @@ -3903,7 +4040,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Time); i { + switch v := v.(*SumTypeVariants); i { case 0: return &v.state case 1: @@ -3915,7 +4052,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type); i { + switch v := v.(*Time); i { case 0: return &v.state case 1: @@ -3927,7 +4064,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TypeParameter); i { + switch v := v.(*Type); i { case 0: return &v.state case 1: @@ -3939,7 +4076,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TypeValue); i { + switch v := v.(*TypeParameter); i { case 0: return &v.state case 1: @@ -3951,7 +4088,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Unit); i { + switch v := v.(*TypeRegistry); i { case 0: return &v.state case 1: @@ -3963,7 +4100,7 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Value); i { + switch v := v.(*TypeValue); i { case 0: return &v.state case 1: @@ -3975,6 +4112,30 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { } } file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Unit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Verb); i { case 0: return &v.state @@ -4034,8 +4195,8 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[31].OneofWrappers = []interface{}{} file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[32].OneofWrappers = []interface{}{} file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[33].OneofWrappers = []interface{}{} - file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[34].OneofWrappers = []interface{}{} - file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35].OneofWrappers = []interface{}{ + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[35].OneofWrappers = []interface{}{} + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36].OneofWrappers = []interface{}{ (*Type_Int)(nil), (*Type_Float)(nil), (*Type_String_)(nil), @@ -4049,22 +4210,22 @@ func file_xyz_block_ftl_v1_schema_schema_proto_init() { (*Type_Ref)(nil), (*Type_Optional)(nil), } - file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[36].OneofWrappers = []interface{}{} file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[37].OneofWrappers = []interface{}{} - file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[38].OneofWrappers = []interface{}{} - file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39].OneofWrappers = []interface{}{ + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[39].OneofWrappers = []interface{}{} + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40].OneofWrappers = []interface{}{} + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[41].OneofWrappers = []interface{}{ (*Value_StringValue)(nil), (*Value_IntValue)(nil), (*Value_TypeValue)(nil), } - file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[40].OneofWrappers = []interface{}{} + file_xyz_block_ftl_v1_schema_schema_proto_msgTypes[42].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_xyz_block_ftl_v1_schema_schema_proto_rawDesc, NumEnums: 0, - NumMessages: 41, + NumMessages: 45, NumExtensions: 0, NumServices: 0, }, diff --git a/backend/protos/xyz/block/ftl/v1/schema/schema.proto b/backend/protos/xyz/block/ftl/v1/schema/schema.proto index de58c1977e..85e067d795 100644 --- a/backend/protos/xyz/block/ftl/v1/schema/schema.proto +++ b/backend/protos/xyz/block/ftl/v1/schema/schema.proto @@ -215,6 +215,10 @@ message StringValue { string value = 2; } +message SumTypeVariants { + repeated string value = 1; +} + message Time { optional Position pos = 1; } @@ -241,6 +245,11 @@ message TypeParameter { string name = 2; } +message TypeRegistry { + map schemaTypes = 1; + map sumTypes = 2; +} + message TypeValue { optional Position pos = 1; Type value = 2; diff --git a/backend/schema/protobuf.go b/backend/schema/protobuf.go index 29ba7b9e0b..79a9028301 100644 --- a/backend/schema/protobuf.go +++ b/backend/schema/protobuf.go @@ -21,8 +21,9 @@ var typesWithRuntime = map[string]bool{ // for the FTL schema. func ProtobufSchema() string { messages := map[string]string{} - generateMessage(reflect.TypeOf(Schema{}), messages) - generateMessage(reflect.TypeOf(ErrorList{}), messages) + generateMessage(reflect.TypeFor[Schema](), messages) + generateMessage(reflect.TypeFor[ErrorList](), messages) + generateMessage(reflect.TypeFor[TypeRegistry](), messages) keys := maps.Keys(messages) slices.Sort(keys) w := &strings.Builder{} diff --git a/backend/schema/type_registry.go b/backend/schema/type_registry.go new file mode 100644 index 0000000000..56a8aa2fab --- /dev/null +++ b/backend/schema/type_registry.go @@ -0,0 +1,71 @@ +package schema + +import ( + "context" + schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" +) + +type contextKeyTypeRegistry struct{} + +// ContextWithTypeRegistry adds a type registry to the given context. +func ContextWithTypeRegistry(ctx context.Context, r *schemapb.TypeRegistry) context.Context { + return context.WithValue(ctx, contextKeyTypeRegistry{}, r) +} + +// TypeRegistry is a registry of types that can be resolved to a schema type at runtime. +// It also records sum types and their variants, for use in encoding and decoding. +type TypeRegistry struct { + // SchemaTypes associates a type name with a schema type. + SchemaTypes map[string]Type `protobuf:"1"` + // SumTypes associates a sum type discriminator type name with its variant type names. + SumTypes map[string]SumTypeVariants `protobuf:"2"` +} + +// NewTypeRegistry creates a new type registry. +// The type registry is used to instantiate types by their qualified name at runtime. +func NewTypeRegistry() *TypeRegistry { + return &TypeRegistry{ + SchemaTypes: make(map[string]Type), + SumTypes: make(map[string]SumTypeVariants), + } +} + +// RegisterSumType registers a Go sum type with the type registry. Sum types are represented as enums in the +// FTL schema. +func (t *TypeRegistry) RegisterSumType(discriminator string, variants map[string]Type) { + var values []string + for name, vt := range variants { + values = append(values, name) + t.SchemaTypes[name] = vt + } + t.SumTypes[discriminator] = SumTypeVariants{Value: values} +} + +func (t *TypeRegistry) ToProto() *schemapb.TypeRegistry { + typespb := make(map[string]*schemapb.Type, len(t.SchemaTypes)) + for k, v := range t.SchemaTypes { + typespb[k] = typeToProto(v) + } + + return &schemapb.TypeRegistry{ + SumTypes: sumTypeVariantsToProto(t.SumTypes), + SchemaTypes: typespb, + } +} + +type SumTypeVariants struct { + // Value is a list of variant names for the sum type. + Value []string `protobuf:"1"` +} + +func (s *SumTypeVariants) ToProto() *schemapb.SumTypeVariants { + return &schemapb.SumTypeVariants{Value: s.Value} +} + +func sumTypeVariantsToProto(v map[string]SumTypeVariants) map[string]*schemapb.SumTypeVariants { + out := make(map[string]*schemapb.SumTypeVariants, len(v)) + for k, v := range v { + out[k] = v.ToProto() + } + return out +} diff --git a/backend/schema/visit.go b/backend/schema/visit.go index c3aa4ab292..56c29716e5 100644 --- a/backend/schema/visit.go +++ b/backend/schema/visit.go @@ -17,6 +17,12 @@ func Visit(n Node, visit func(n Node, next func() error) error) error { // stubbed verbs. func VisitExcludingMetadataChildren(n Node, visit func(n Node, next func() error) error) error { return visit(n, func() error { + if d, ok := n.(Decl); ok { + if !d.IsExported() { + // Skip non-exported nodes + return nil + } + } if _, ok := n.(Metadata); !ok { for _, child := range n.schemaChildren() { _, isParentVerb := n.(*Verb) diff --git a/buildengine/build_go_test.go b/buildengine/build_go_test.go index f4cd43dbed..d59db635bf 100644 --- a/buildengine/build_go_test.go +++ b/buildengine/build_go_test.go @@ -2,9 +2,12 @@ package buildengine import ( "fmt" + "os" "runtime" "testing" + "github.com/alecthomas/assert/v2" + "github.com/TBD54566975/ftl/backend/schema" ) @@ -261,58 +264,14 @@ func TestGeneratedTypeRegistry(t *testing.T) { }}, }, } - expected := `// Code generated by FTL. DO NOT EDIT. -package main - -import ( - "context" - "reflect" - - "github.com/TBD54566975/ftl/common/plugin" - "github.com/TBD54566975/ftl/go-runtime/server" - "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" - "github.com/TBD54566975/ftl/go-runtime/ftl" - - "ftl/other" - "ftl/another" -) - -func main() { - verbConstructor := server.NewUserVerbServer("other", - server.HandleCall(other.Echo), - ) - ctx := context.Background() - typeRegistry := ftl.NewTypeRegistry() - typeRegistry.RegisterSumType(reflect.TypeFor[other.D](), map[string]reflect.Type{ - "Bool": reflect.TypeFor[other.Bool](), - "Bytes": reflect.TypeFor[other.Bytes](), - "Float": reflect.TypeFor[other.Float](), - "Int": reflect.TypeFor[other.Int](), - "U": reflect.TypeFor[other.U](), - "List": reflect.TypeFor[other.List](), - "Map": reflect.TypeFor[other.Map](), - "String": reflect.TypeFor[other.String](), - "Struct": reflect.TypeFor[other.Struct](), - }) - typeRegistry.RegisterSumType(reflect.TypeFor[other.SecondSumType](), map[string]reflect.Type{ - "A": reflect.TypeFor[other.A](), - "B": reflect.TypeFor[other.B](), - }) - typeRegistry.RegisterSumType(reflect.TypeFor[another.TypeEnum](), map[string]reflect.Type{ - "A": reflect.TypeFor[another.A](), - "B": reflect.TypeFor[another.B](), - }) - ctx = context.WithValue(ctx, "typeRegistry", typeRegistry) - - plugin.Start(ctx, "other", verbConstructor, ftlv1connect.VerbServiceName, ftlv1connect.NewVerbServiceHandler) -} -` + expected, err := os.ReadFile("testdata/type_registry_main.go") + assert.NoError(t, err) bctx := buildContext{ moduleDir: "testdata/projects/other", buildDir: "_ftl", sch: sch, } testBuild(t, bctx, "", []assertion{ - assertGeneratedMain(expected), + assertGeneratedMain(string(expected)), }) } diff --git a/buildengine/testdata/projects/other/other.go b/buildengine/testdata/projects/other/other.go index 235fb3820b..2d10057801 100644 --- a/buildengine/testdata/projects/other/other.go +++ b/buildengine/testdata/projects/other/other.go @@ -3,6 +3,7 @@ package other import ( "context" "fmt" + "time" "github.com/TBD54566975/ftl/go-runtime/ftl" // Import the FTL SDK. @@ -10,7 +11,7 @@ import ( ) //ftl:enum -type D interface { +type TypeEnum interface { tag() } @@ -30,13 +31,9 @@ type Int int func (Int) tag() {} -//type Time time.Time -// -//func (Time) tag() {} +type Time time.Time -type U ftl.Unit - -func (U) tag() {} +func (Time) tag() {} type List []string @@ -54,8 +51,16 @@ type Struct struct{} func (Struct) tag() {} +type Option ftl.Option[string] + +func (Option) tag() {} + +type Unit ftl.Unit + +func (Unit) tag() {} + //ftl:enum -type SecondSumType interface { +type SecondTypeEnum interface { tag2() } diff --git a/buildengine/testdata/type_registry_main.go b/buildengine/testdata/type_registry_main.go new file mode 100644 index 0000000000..dadfad7ef6 --- /dev/null +++ b/buildengine/testdata/type_registry_main.go @@ -0,0 +1,72 @@ +// Code generated by FTL. DO NOT EDIT. +package main + +import ( + "context" + "reflect" + + "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" + "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/common/plugin" + "github.com/TBD54566975/ftl/go-runtime/ftl/typeregistry" + "github.com/TBD54566975/ftl/go-runtime/server" + + "ftl/another" + "ftl/other" +) + +func main() { + verbConstructor := server.NewUserVerbServer("other", + server.HandleCall(other.Echo), + ) + ctx := context.Background() + + goTypeRegistry := typeregistry.NewTypeRegistry() + schemaTypeRegistry := schema.NewTypeRegistry() + goTypeRegistry.RegisterSumType(reflect.TypeFor[another.TypeEnum](), map[string]reflect.Type{ + "A": reflect.TypeFor[another.A](), + "B": reflect.TypeFor[another.B](), + }) + schemaTypeRegistry.RegisterSumType("another.TypeEnum", map[string]schema.Type{ + "A": &schema.Int{}, + "B": &schema.String{}, + }) + goTypeRegistry.RegisterSumType(reflect.TypeFor[other.SecondTypeEnum](), map[string]reflect.Type{ + "A": reflect.TypeFor[other.A](), + "B": reflect.TypeFor[other.B](), + }) + schemaTypeRegistry.RegisterSumType("other.SecondTypeEnum", map[string]schema.Type{ + "A": &schema.String{}, + "B": &schema.Ref{Module: "other", Name: "B"}, + }) + goTypeRegistry.RegisterSumType(reflect.TypeFor[other.TypeEnum](), map[string]reflect.Type{ + "Bool": reflect.TypeFor[other.Bool](), + "Bytes": reflect.TypeFor[other.Bytes](), + "Float": reflect.TypeFor[other.Float](), + "Int": reflect.TypeFor[other.Int](), + "Time": reflect.TypeFor[other.Time](), + "List": reflect.TypeFor[other.List](), + "Map": reflect.TypeFor[other.Map](), + "String": reflect.TypeFor[other.String](), + "Struct": reflect.TypeFor[other.Struct](), + "Option": reflect.TypeFor[other.Option](), + "Unit": reflect.TypeFor[other.Unit](), + }) + schemaTypeRegistry.RegisterSumType("other.TypeEnum", map[string]schema.Type{ + "Bool": &schema.Bool{}, + "Bytes": &schema.Bytes{}, + "Float": &schema.Float{}, + "Int": &schema.Int{}, + "Time": &schema.Time{}, + "List": &schema.Array{Element: &schema.String{}}, + "Map": &schema.Map{Key: &schema.String{}, Value: &schema.String{}}, + "String": &schema.String{}, + "Struct": &schema.Ref{Module: "other", Name: "Struct"}, + "Option": &schema.Optional{Type: &schema.String{}}, + "Unit": &schema.Unit{}, + }) + ctx = typeregistry.ContextWithTypeRegistry(ctx, goTypeRegistry) + ctx = schema.ContextWithTypeRegistry(ctx, schemaTypeRegistry.ToProto()) + + plugin.Start(ctx, "other", verbConstructor, ftlv1connect.VerbServiceName, ftlv1connect.NewVerbServiceHandler) +} diff --git a/frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts b/frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts index dda3ef20ee..6aa2a1a43e 100644 --- a/frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts +++ b/frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts @@ -1679,6 +1679,43 @@ export class StringValue extends Message { } } +/** + * @generated from message xyz.block.ftl.v1.schema.SumTypeVariants + */ +export class SumTypeVariants extends Message { + /** + * @generated from field: repeated string value = 1; + */ + value: string[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.v1.schema.SumTypeVariants"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): SumTypeVariants { + return new SumTypeVariants().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): SumTypeVariants { + return new SumTypeVariants().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): SumTypeVariants { + return new SumTypeVariants().fromJsonString(jsonString, options); + } + + static equals(a: SumTypeVariants | PlainMessage | undefined, b: SumTypeVariants | PlainMessage | undefined): boolean { + return proto3.util.equals(SumTypeVariants, a, b); + } +} + /** * @generated from message xyz.block.ftl.v1.schema.Time */ @@ -1879,6 +1916,49 @@ export class TypeParameter extends Message { } } +/** + * @generated from message xyz.block.ftl.v1.schema.TypeRegistry + */ +export class TypeRegistry extends Message { + /** + * @generated from field: map schemaTypes = 1; + */ + schemaTypes: { [key: string]: Type } = {}; + + /** + * @generated from field: map sumTypes = 2; + */ + sumTypes: { [key: string]: SumTypeVariants } = {}; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.v1.schema.TypeRegistry"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "schemaTypes", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "message", T: Type} }, + { no: 2, name: "sumTypes", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "message", T: SumTypeVariants} }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): TypeRegistry { + return new TypeRegistry().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): TypeRegistry { + return new TypeRegistry().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): TypeRegistry { + return new TypeRegistry().fromJsonString(jsonString, options); + } + + static equals(a: TypeRegistry | PlainMessage | undefined, b: TypeRegistry | PlainMessage | undefined): boolean { + return proto3.util.equals(TypeRegistry, a, b); + } +} + /** * @generated from message xyz.block.ftl.v1.schema.TypeValue */ diff --git a/go-runtime/compile/build-template/_ftl.tmpl/go/main/main.go b/go-runtime/compile/build-template/_ftl.tmpl/go/main/main.go index 6072b4eeec..f72dff2f6f 100644 --- a/go-runtime/compile/build-template/_ftl.tmpl/go/main/main.go +++ b/go-runtime/compile/build-template/_ftl.tmpl/go/main/main.go @@ -6,12 +6,15 @@ import ( {{- if .SumTypes }} "reflect" {{ end }} - "github.com/TBD54566975/ftl/common/plugin" - "github.com/TBD54566975/ftl/go-runtime/server" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" {{- if .SumTypes }} - "github.com/TBD54566975/ftl/go-runtime/ftl" + "github.com/TBD54566975/ftl/backend/schema" +{{- end }} + "github.com/TBD54566975/ftl/common/plugin" +{{- if .SumTypes }} + "github.com/TBD54566975/ftl/go-runtime/ftl/typeregistry" {{- end }} + "github.com/TBD54566975/ftl/go-runtime/server" {{ range mainImports . }} "ftl/{{.}}" {{- end}} @@ -33,19 +36,27 @@ func main() { ) ctx := context.Background() - {{- if .SumTypes}} - typeRegistry := ftl.NewTypeRegistry() - {{- end}} - {{- range .SumTypes}} - typeRegistry.RegisterSumType(reflect.TypeFor[{{.Discriminator}}](), map[string]reflect.Type{ +{{- if .SumTypes}} + + goTypeRegistry := typeregistry.NewTypeRegistry() + schemaTypeRegistry := schema.NewTypeRegistry() +{{- end}} +{{- range .SumTypes}} + goTypeRegistry.RegisterSumType(reflect.TypeFor[{{.Discriminator}}](), map[string]reflect.Type{ {{- range .Variants}} "{{.Name}}": reflect.TypeFor[{{.Type}}](), {{- end}} }) - {{- end}} - {{- if .SumTypes}} - ctx = context.WithValue(ctx, "typeRegistry", typeRegistry) - {{- end}} + schemaTypeRegistry.RegisterSumType("{{.Discriminator}}", map[string]schema.Type{ + {{- range .Variants}} + "{{.Name}}": {{schemaType .SchemaType}}, + {{- end}} + }) +{{- end}} +{{- if .SumTypes}} + ctx = typeregistry.ContextWithTypeRegistry(ctx, goTypeRegistry) + ctx = schema.ContextWithTypeRegistry(ctx, schemaTypeRegistry.ToProto()) +{{- end}} plugin.Start(ctx, "{{.Name}}", verbConstructor, ftlv1connect.VerbServiceName, ftlv1connect.NewVerbServiceHandler) } diff --git a/go-runtime/compile/build.go b/go-runtime/compile/build.go index 91aeb6bbef..b35f3d8b58 100644 --- a/go-runtime/compile/build.go +++ b/go-runtime/compile/build.go @@ -10,6 +10,7 @@ import ( "path/filepath" stdreflect "reflect" "runtime" + "slices" "strconv" "strings" "unicode" @@ -61,8 +62,9 @@ type goSumType struct { } type goSumTypeVariant struct { - Name string - Type string + Name string + Type string + SchemaType schema.Type } type ModifyFilesTransaction interface { @@ -140,7 +142,11 @@ func Build(ctx context.Context, moduleDir string, sch *schema.Schema, filesTrans if err != nil { return fmt.Errorf("failed to extract module schema: %w", err) } - pr := parseResult.MustGet() + pr, ok := parseResult.Get() + if !ok { + return fmt.Errorf("failed to extract module schema") + } + main := pr.Module if schemaErrs := pr.Errors; len(schemaErrs) > 0 { if err := writeSchemaErrors(config, schemaErrs); err != nil { @@ -344,8 +350,27 @@ var scaffoldFuncs = scaffolder.FuncMap{ } } } - return imports.ToSlice() + out := imports.ToSlice() + slices.Sort(out) + return out }, + "schemaType": schemaType, +} + +func schemaType(t schema.Type) string { + switch t := t.(type) { + case *schema.Int, *schema.Bool, *schema.String, *schema.Float, *schema.Unit, *schema.Any, *schema.Bytes, *schema.Time: + return fmt.Sprintf("&%s{}", strings.TrimLeft(stdreflect.TypeOf(t).String(), "*")) + case *schema.Ref: + return fmt.Sprintf("&schema.Ref{Module: %q, Name: %q}", t.Module, t.Name) + case *schema.Array: + return fmt.Sprintf("&schema.Array{Element: %s}", schemaType(t.Element)) + case *schema.Map: + return fmt.Sprintf("&schema.Map{Key: %s, Value: %s}", schemaType(t.Key), schemaType(t.Value)) + case *schema.Optional: + return fmt.Sprintf("&schema.Optional{Type: %s}", schemaType(t.Type)) + } + panic(fmt.Sprintf("unsupported type %T", t)) } func genType(module *schema.Module, t schema.Type) string { @@ -483,9 +508,10 @@ func getSumTypes(enumRefs []*schema.Ref, module *schema.Module, sch *schema.Sche if e, ok := d.(*schema.Enum); ok && !e.IsValueEnum() { variants := make([]goSumTypeVariant, 0, len(e.Variants)) for _, v := range e.Variants { - variants = append(variants, goSumTypeVariant{ - Name: v.Name, - Type: nativeNames[v], + variants = append(variants, goSumTypeVariant{ //nolint:forcetypeassert + Name: v.Name, + Type: nativeNames[v], + SchemaType: v.Value.(*schema.TypeValue).Value, }) } stFqName := nativeNames[d] @@ -505,9 +531,10 @@ func getSumTypes(enumRefs []*schema.Ref, module *schema.Module, sch *schema.Sche if e, ok := resolved.(*schema.Enum); ok && !e.IsValueEnum() { variants := make([]goSumTypeVariant, 0, len(e.Variants)) for _, v := range e.Variants { - variants = append(variants, goSumTypeVariant{ - Name: v.Name, - Type: ref.Module + "." + v.Name, + variants = append(variants, goSumTypeVariant{ //nolint:forcetypeassert + Name: v.Name, + Type: ref.Module + "." + v.Name, + SchemaType: v.Value.(*schema.TypeValue).Value, }) } stFqName := ref.Module + "." + e.Name @@ -517,5 +544,9 @@ func getSumTypes(enumRefs []*schema.Ref, module *schema.Module, sch *schema.Sche } } } - return gomaps.Values(sumTypes) + out := gomaps.Values(sumTypes) + slices.SortFunc(out, func(a, b goSumType) int { + return strings.Compare(a.Discriminator, b.Discriminator) + }) + return out } diff --git a/go-runtime/compile/schema.go b/go-runtime/compile/schema.go index f94f623cda..5edb026a0f 100644 --- a/go-runtime/compile/schema.go +++ b/go-runtime/compile/schema.go @@ -38,6 +38,7 @@ var ( ftlSecretFuncPath = "github.com/TBD54566975/ftl/go-runtime/ftl.Secret" //nolint:gosec ftlPostgresDBFuncPath = "github.com/TBD54566975/ftl/go-runtime/ftl.PostgresDatabase" ftlUnitTypePath = "github.com/TBD54566975/ftl/go-runtime/ftl.Unit" + ftlOptionTypePath = "github.com/TBD54566975/ftl/go-runtime/ftl.Option" aliasFieldTag = "json" ) @@ -107,7 +108,7 @@ func ExtractModuleSchema(dir string) (optional.Option[ParseResult], error) { pkgs, err := packages.Load(&packages.Config{ Dir: dir, Fset: fset, - Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo, + Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports, }, "./...") if err != nil { return optional.None[ParseResult](), err @@ -534,8 +535,8 @@ func maybeVisitTypeEnumVariant(pctx *parseContext, node *ast.GenDecl, directives isExported = exportableDir.IsExported() } } - if typ, ok := visitType(pctx, node.Pos(), named, isExported).Get(); ok { - enumVariant.Value = &schema.TypeValue{Value: typ} + if vType, ok := visitTypeValue(pctx, named, t.Type, nil, isExported).Get(); ok { + enumVariant.Value = vType } else { pctx.errors.add(errorf(node, "unsupported type %q for type enum variant", named)) } @@ -548,6 +549,78 @@ func maybeVisitTypeEnumVariant(pctx *parseContext, node *ast.GenDecl, directives return false } +func visitTypeValue(pctx *parseContext, named *types.Named, tnode ast.Expr, index types.Type, isExported bool) optional.Option[*schema.TypeValue] { + switch typ := tnode.(type) { + // Selector expression e.g. ftl.Unit, ftl.Option, foo.Bar + case *ast.SelectorExpr: + var ident *ast.Ident + var ok bool + if ident, ok = typ.X.(*ast.Ident); !ok { + return optional.None[*schema.TypeValue]() + } + + for _, im := range maps.Values(pctx.pkg.Imports) { + if im.Name != ident.Name { + continue + } + switch im.ID + "." + typ.Sel.Name { + case "time.Time": + return optional.Some(&schema.TypeValue{ + Pos: goPosToSchemaPos(tnode.Pos()), + Value: &schema.Time{}, + }) + case ftlUnitTypePath: + return optional.Some(&schema.TypeValue{ + Pos: goPosToSchemaPos(tnode.Pos()), + Value: &schema.Unit{}, + }) + case ftlOptionTypePath: + if index == nil { + return optional.None[*schema.TypeValue]() + } + + if vt, ok := visitType(pctx, tnode.Pos(), index, isExported).Get(); ok { + return optional.Some(&schema.TypeValue{ + Pos: goPosToSchemaPos(tnode.Pos()), + Value: &schema.Optional{ + Pos: goPosToSchemaPos(tnode.Pos()), + Type: vt, + }, + }) + } + default: // Data ref + externalModuleName, ok := ftlModuleFromGoModule(im.ID).Get() + if !ok { + pctx.errors.add(errorf(tnode, "package %q is not in the ftl namespace", im.ID)) + return optional.None[*schema.TypeValue]() + } + return optional.Some(&schema.TypeValue{ + Pos: goPosToSchemaPos(tnode.Pos()), + Value: &schema.Ref{ + Pos: goPosToSchemaPos(tnode.Pos()), + Module: externalModuleName, + Name: typ.Sel.Name, + }, + }) + } + } + + case *ast.IndexExpr: // Generic type, e.g. ftl.Option[string] + if se, ok := typ.X.(*ast.SelectorExpr); ok { + return visitTypeValue(pctx, named, se, pctx.pkg.TypesInfo.TypeOf(typ.Index), isExported) + } + + default: + if typ, ok := visitType(pctx, tnode.Pos(), named, isExported).Get(); ok { + return optional.Some(&schema.TypeValue{Value: typ}) + } else { + pctx.errors.add(errorf(tnode, "unsupported type %q for type enum variant", named)) + } + } + + return optional.None[*schema.TypeValue]() +} + func visitValueSpec(pctx *parseContext, node *ast.ValueSpec) { var enum *schema.Enum i, ok := node.Type.(*ast.Ident) @@ -891,10 +964,7 @@ func visitType(pctx *parseContext, pos token.Pos, tnode types.Type, isExported b if _, ok := visitType(pctx, pos, named.Underlying(), isExported).Get(); !ok { return optional.None[schema.Type]() } - enumRef, doneWithVisit := visitEnumType(pctx, pos, named) - if er, ok := enumRef.Get(); ok { - pctx.enumRefs[named.Obj().Name()] = er.(*schema.Ref) //nolint:forcetypeassert - } + enumRef, doneWithVisit := visitEnumRef(pctx, pos, named) if doneWithVisit { return enumRef } @@ -920,9 +990,7 @@ func visitType(pctx *parseContext, pos token.Pos, tnode types.Type, isExported b case *types.Struct: named, ok := tnode.(*types.Named) if !ok { - if ref, ok := visitStruct(pctx, pos, tnode, isExported).Get(); ok { - return optional.Some[schema.Type](ref) - } + pctx.errors.add(noEndColumnErrorf(pos, "expected named type but got %s", tnode)) return optional.None[schema.Type]() } @@ -963,10 +1031,7 @@ func visitType(pctx *parseContext, pos token.Pos, tnode types.Type, isExported b return optional.Some[schema.Type](&schema.Any{Pos: goPosToSchemaPos(pos)}) } if named, ok := tnode.(*types.Named); ok { - enumRef, doneWithVisit := visitEnumType(pctx, pos, named) - if er, ok := enumRef.Get(); ok { - pctx.enumRefs[named.Obj().Name()] = er.(*schema.Ref) //nolint:forcetypeassert - } + enumRef, doneWithVisit := visitEnumRef(pctx, pos, named) if doneWithVisit { return enumRef } @@ -978,14 +1043,19 @@ func visitType(pctx *parseContext, pos token.Pos, tnode types.Type, isExported b } } -func visitEnumType(pctx *parseContext, pos token.Pos, named *types.Named) (optional.Option[schema.Type], bool) { - if pctx.enums[named.Obj().Name()] != nil { - return optional.Some[schema.Type](&schema.Ref{ - Pos: goPosToSchemaPos(pos), - Module: pctx.module.Name, - Name: named.Obj().Name(), - }), true +func visitEnumRef(pctx *parseContext, pos token.Pos, named *types.Named) (optional.Option[schema.Type], bool) { + enumRef, doneWithVisit := visitEnumType(pctx, pos, named) + if er, ok := enumRef.Get(); ok { + refModuleName, ok := ftlModuleFromGoModule(named.Obj().Pkg().Path()).Get() + if !ok { + refModuleName = named.Obj().Pkg().Path() + } + pctx.enumRefs[refModuleName+"."+named.Obj().Name()] = er.(*schema.Ref) //nolint:forcetypeassert } + return enumRef, doneWithVisit +} + +func visitEnumType(pctx *parseContext, pos token.Pos, named *types.Named) (optional.Option[schema.Type], bool) { if named.Obj().Pkg() == nil { return optional.None[schema.Type](), false } @@ -1006,6 +1076,12 @@ func visitEnumType(pctx *parseContext, pos token.Pos, named *types.Named) (optio Module: destModule, Name: named.Obj().Name(), }), true + } else if pctx.enums[named.Obj().Name()] != nil { + return optional.Some[schema.Type](&schema.Ref{ + Pos: goPosToSchemaPos(pos), + Module: pctx.module.Name, + Name: named.Obj().Name(), + }), true } return optional.None[schema.Type](), false } diff --git a/go-runtime/ftl/type_registry.go b/go-runtime/ftl/typeregistry/type_registry.go similarity index 58% rename from go-runtime/ftl/type_registry.go rename to go-runtime/ftl/typeregistry/type_registry.go index 35719ac4b5..2ce7b0094c 100644 --- a/go-runtime/ftl/type_registry.go +++ b/go-runtime/ftl/typeregistry/type_registry.go @@ -1,34 +1,41 @@ -package ftl +package typeregistry import ( + "context" "fmt" "reflect" ) +type contextKeyTypeRegistry struct{} + +// ContextWithTypeRegistry adds a type registry to the given context. +func ContextWithTypeRegistry(ctx context.Context, r *TypeRegistry) context.Context { + return context.WithValue(ctx, contextKeyTypeRegistry{}, r) +} + // TypeRegistry is a registry of types that can be instantiated by their qualified name. // It also records sum types and their variants, for use in encoding and decoding. // -// FTL manages the type registry for you, so you don't need to create one yourself. +// FTL manages the type registry for you, so you don't need to create one yourself type TypeRegistry struct { - // sumTypes associates a sum type discriminator with its variants - sumTypes map[string][]sumTypeVariant - types map[string]reflect.Type -} - -type sumTypeVariant struct { - name string - typeName string + // GoTypes associates a type name with a Go type. + GoTypes map[string]reflect.Type + // SumTypes associates a sum type discriminator type name with its variant type names. + SumTypes map[string][]string } // NewTypeRegistry creates a new type registry. // The type registry is used to instantiate types by their qualified name at runtime. func NewTypeRegistry() *TypeRegistry { - return &TypeRegistry{types: map[string]reflect.Type{}, sumTypes: map[string][]sumTypeVariant{}} + return &TypeRegistry{ + GoTypes: make(map[string]reflect.Type), + SumTypes: make(map[string][]string), + } } // New creates a new instance of the type from the qualified type name. func (t *TypeRegistry) New(name string) (any, error) { - typ, ok := t.types[name] + typ, ok := t.GoTypes[name] if !ok { return nil, fmt.Errorf("type %q not registered", name) } @@ -39,12 +46,13 @@ func (t *TypeRegistry) New(name string) (any, error) { // FTL schema. func (t *TypeRegistry) RegisterSumType(discriminator reflect.Type, variants map[string]reflect.Type) { dFqName := discriminator.PkgPath() + "." + discriminator.Name() - t.types[dFqName] = discriminator - t.sumTypes[dFqName] = make([]sumTypeVariant, 0, len(variants)) + t.GoTypes[dFqName] = discriminator + var values []string for name, v := range variants { + values = append(values, name) vFqName := v.PkgPath() + "." + v.Name() - t.types[vFqName] = v - t.sumTypes[dFqName] = append(t.sumTypes[dFqName], sumTypeVariant{name: name, typeName: vFqName}) + t.GoTypes[vFqName] = v } + t.SumTypes[dFqName] = values }