diff --git a/encoding/protobq/integration_test.go b/encoding/protobq/integration_test.go index 11c5291..b48d23d 100644 --- a/encoding/protobq/integration_test.go +++ b/encoding/protobq/integration_test.go @@ -41,21 +41,23 @@ func Test_Integration_PublicDataSets(t *testing.T) { Message: &publicv1.FilmLocation{}, }, - { - ProjectID: "bigquery-public-data", - DatasetID: "hacker_news", - TableID: "stories", - Limit: 10, - Message: &publicv1.HackerNewsStory{}, - }, + // no longer accessible + // { + // ProjectID: "bigquery-public-data", + // DatasetID: "hacker_news", + // TableID: "stories", + // Limit: 10, + // Message: &publicv1.HackerNewsStory{}, + // }, - { - ProjectID: "bigquery-public-data", - DatasetID: "london_bicycles", - TableID: "cycle_hire", - Limit: 10, - Message: &publicv1.LondonBicycleRental{}, - }, + // no longer accessible + // { + // ProjectID: "bigquery-public-data", + // DatasetID: "london_bicycles", + // TableID: "cycle_hire", + // Limit: 10, + // Message: &publicv1.LondonBicycleRental{}, + // }, { ProjectID: "bigquery-public-data", @@ -65,16 +67,17 @@ func Test_Integration_PublicDataSets(t *testing.T) { Message: &publicv1.SanFransiscoTransitStopTime{}, }, - { - ProjectID: "bigquery-public-data", - DatasetID: "london_bicycles", - TableID: "cycle_stations", - Limit: 10, - Message: &publicv1.LondonBicycleStation{}, - UnmarshalOptions: protobq.UnmarshalOptions{ - DiscardUnknown: true, // Ignore non-snake case field "nbEmptyDocks". - }, - }, + // no longer accessible + // { + // ProjectID: "bigquery-public-data", + // DatasetID: "london_bicycles", + // TableID: "cycle_stations", + // Limit: 10, + // Message: &publicv1.LondonBicycleStation{}, + // UnmarshalOptions: protobq.UnmarshalOptions{ + // DiscardUnknown: true, // Ignore non-snake case field "nbEmptyDocks". + // }, + // }, { ProjectID: "bigquery-public-data", diff --git a/encoding/protobq/marshal.go b/encoding/protobq/marshal.go index 39b2dac..d8ec633 100644 --- a/encoding/protobq/marshal.go +++ b/encoding/protobq/marshal.go @@ -28,6 +28,8 @@ func Marshal(msg proto.Message) (map[string]bigquery.Value, error) { type MarshalOptions struct { // Schema contains the schema options. Schema SchemaOptions + + DiscardUnknownEnumValues bool } // Marshal marshals the given proto.Message in the BigQuery format using options in @@ -80,10 +82,14 @@ func (o MarshalOptions) marshalMessage(msg protoreflect.Message) (map[string]big if o.Schema.UseOneofFields { for i := 0; i < msg.Descriptor().Oneofs().Len(); i++ { oneofDescriptor := msg.Descriptor().Oneofs().Get(i) + if oneofDescriptor.IsSynthetic() { + continue + } oneofField := msg.WhichOneof(oneofDescriptor) - if oneofField != nil { - result[string(oneofDescriptor.Name())] = string(oneofField.Name()) + if oneofField == nil { + continue } + result[string(oneofDescriptor.Name())] = string(oneofField.Name()) } } return result, nil @@ -262,7 +268,12 @@ func (o MarshalOptions) marshalEnumValue( if enumValue := field.Enum().Values().ByNumber(enumNumber); enumValue != nil { return string(enumValue.Name()), nil } - return nil, fmt.Errorf("unknown enum number: %v", value.Enum()) + if o.DiscardUnknownEnumValues { + // Use 'null' for BQ rows to indicate that no value could be determined. + return nil, nil + } + path := fmt.Sprintf("%s.%s", field.Parent().FullName(), field.Name()) + return nil, fmt.Errorf("unknown enum number: %v, fieldname: %v", value.Enum(), path) } func (o MarshalOptions) marshalWellKnownTypeValue( diff --git a/encoding/protobq/marshal_test.go b/encoding/protobq/marshal_test.go index 291c484..f901f3b 100644 --- a/encoding/protobq/marshal_test.go +++ b/encoding/protobq/marshal_test.go @@ -1,6 +1,7 @@ package protobq import ( + "fmt" "testing" "time" @@ -335,12 +336,70 @@ func TestMarshalOptions_Marshal(t *testing.T) { opt: MarshalOptions{Schema: SchemaOptions{UseOneofFields: true}}, expected: map[string]bigquery.Value{}, }, + + { + name: "optional oneof and optional message", + msg: &examplev1.ExampleOptional{ + OptMessage_2: &examplev1.ExampleOptMessage{ + StringValue: "opt_message_string_value", + }, + OptOneofMessage_3: &examplev1.ExampleOptOneof{ + OneofFields_1: &examplev1.ExampleOptOneof_OneofMessage_2{ + OneofMessage_2: &examplev1.ExampleOptOneof_Message{ + StringValue: "opt_one_of_message_string_value", + }, + }, + }, + }, + opt: MarshalOptions{Schema: SchemaOptions{UseOneofFields: true}}, + expected: map[string]bigquery.Value{ + "opt_message_2": map[string]bigquery.Value{"string_value": string("opt_message_string_value")}, + "opt_oneof_message_3": map[string]bigquery.Value{ + "oneof_fields_1": string("oneof_message_2"), + "oneof_message_2": map[string]bigquery.Value{"string_value": string("opt_one_of_message_string_value")}, + }, + }, + }, + + { + name: "optional empty oneof and optional empty message", + msg: &examplev1.ExampleOptional{ + OptMessage_2: nil, + OptOneofMessage_3: nil, + }, + opt: MarshalOptions{Schema: SchemaOptions{UseOneofFields: true}}, + expected: map[string]bigquery.Value{}, + }, + + { + name: "allow unknown enum values", + msg: &examplev1.ExampleEnum{ + EnumValue: examplev1.ExampleEnum_Enum(100), + }, + opt: MarshalOptions{Schema: SchemaOptions{UseOneofFields: true}, DiscardUnknownEnumValues: true}, + expected: map[string]bigquery.Value{ + "enum_value": nil, + }, + }, + { + name: "disallow unknown enum values", + msg: &examplev1.ExampleEnum{ + EnumValue: examplev1.ExampleEnum_Enum(100), + }, + opt: MarshalOptions{Schema: SchemaOptions{UseOneofFields: true}, DiscardUnknownEnumValues: false}, + expected: nil, + }, } { tt := tt t.Run(tt.name, func(t *testing.T) { actual, err := tt.opt.Marshal(tt.msg) - assert.NilError(t, err) - assert.DeepEqual(t, tt.expected, actual) + if tt.expected == nil { + fmt.Println(err) + assert.Error(t, err, "unknown enum number: 100, fieldname: einride.bigquery.example.v1.ExampleEnum.enum_value") + } else { + assert.NilError(t, err) + assert.DeepEqual(t, tt.expected, actual) + } }) } } diff --git a/encoding/protobq/schema_test.go b/encoding/protobq/schema_test.go index af754c7..2bdca6b 100644 --- a/encoding/protobq/schema_test.go +++ b/encoding/protobq/schema_test.go @@ -394,10 +394,32 @@ func TestSchemaOptions_InferSchema(t *testing.T) { msg: &examplev1.ExampleOptional{}, expected: bigquery.Schema{ { - Name: "opt", + Name: "opt_double_1", Type: bigquery.FloatFieldType, Required: false, }, + { + Name: "opt_message_2", + Type: "RECORD", + Schema: bigquery.Schema{{Name: "string_value", Type: bigquery.StringFieldType}}, + }, + { + Name: "opt_oneof_message_3", + Type: bigquery.RecordFieldType, + Required: false, + Schema: bigquery.Schema{ + { + Name: "oneof_message_2", + Type: bigquery.RecordFieldType, + Schema: bigquery.Schema{{Name: "string_value", Type: bigquery.StringFieldType}}, + }, + { + Name: "oneof_fields_1", + Description: "One of: oneof_empty_message_1, oneof_message_2.", + Type: bigquery.StringFieldType, + }, + }, + }, }, }, } { diff --git a/encoding/protobq/unmarshal.go b/encoding/protobq/unmarshal.go index 87296a6..4e7daf4 100644 --- a/encoding/protobq/unmarshal.go +++ b/encoding/protobq/unmarshal.go @@ -37,6 +37,10 @@ type UnmarshalOptions struct { // If DiscardUnknown is set, unknown fields are ignored. DiscardUnknown bool + + // If DiscardUnknownEnumValues is set, unknown enum values are set to the empty value. + // For compatibility, this is independent of the complementary DiscardUnknown option. + DiscardUnknownEnumValues bool } // Unmarshal reads the given BigQuery row and populates the given proto.Message using @@ -635,20 +639,31 @@ func (o UnmarshalOptions) unmarshalEnumScalar( if o.Schema.UseEnumNumbers { v, ok := bqValue.(int64) if !ok { + if o.DiscardUnknownEnumValues { + return protoreflect.Value{}, nil + } return protoreflect.Value{}, fmt.Errorf( "invalid BigQuery value %#v for enum %s number", bqValue, field.Enum().FullName(), ) } return protoreflect.ValueOfEnum(protoreflect.EnumNumber(int32(v))), nil } + v, ok := bqValue.(string) if !ok { + if o.DiscardUnknownEnumValues { + return protoreflect.Value{}, nil + } return protoreflect.Value{}, fmt.Errorf( "invalid BigQuery value %#v for enum %s", bqValue, field.Enum().FullName(), ) } + enumVal := field.Enum().Values().ByName(protoreflect.Name(v)) if enumVal == nil { + if o.DiscardUnknownEnumValues { + return protoreflect.Value{}, nil + } return protoreflect.Value{}, fmt.Errorf( "unknown enum value %#v for enum %s", bqValue, field.Enum().FullName(), ) diff --git a/encoding/protobq/unmarshal_test.go b/encoding/protobq/unmarshal_test.go index 0f3eb25..d37172e 100644 --- a/encoding/protobq/unmarshal_test.go +++ b/encoding/protobq/unmarshal_test.go @@ -400,6 +400,27 @@ func TestUnmarshalOptions_Unmarshal(t *testing.T) { opt: UnmarshalOptions{Schema: SchemaOptions{UseOneofFields: true}}, expected: &examplev1.ExampleOneof{}, }, + + { + name: "discard unknown enum string", + row: map[string]bigquery.Value{"enum_value": "ENUM_VALUE_100"}, + opt: UnmarshalOptions{DiscardUnknownEnumValues: true}, + expected: &examplev1.ExampleEnum{EnumValue: examplev1.ExampleEnum_ENUM_UNSPECIFIED}, + }, + + { + name: "discard unknown enum number", + row: map[string]bigquery.Value{"enum_value": 100}, + opt: UnmarshalOptions{DiscardUnknownEnumValues: true}, + expected: &examplev1.ExampleEnum{EnumValue: examplev1.ExampleEnum_ENUM_UNSPECIFIED}, + }, + + { + name: "discard enum null", + row: map[string]bigquery.Value{"enum_value": nil}, + opt: UnmarshalOptions{DiscardUnknownEnumValues: true}, + expected: &examplev1.ExampleEnum{EnumValue: examplev1.ExampleEnum_ENUM_UNSPECIFIED}, + }, } { tt := tt t.Run(tt.name, func(t *testing.T) { diff --git a/internal/examples/proto/einride/bigquery/example/v1/example_optional.proto b/internal/examples/proto/einride/bigquery/example/v1/example_optional.proto index 2a27178..da6aabc 100644 --- a/internal/examples/proto/einride/bigquery/example/v1/example_optional.proto +++ b/internal/examples/proto/einride/bigquery/example/v1/example_optional.proto @@ -3,5 +3,22 @@ syntax = "proto3"; package einride.bigquery.example.v1; message ExampleOptional { - optional double opt = 1; + optional double opt_double_1 = 1; + optional ExampleOptMessage opt_message_2 = 2; + optional ExampleOptOneof opt_oneof_message_3 = 3; +} + +message ExampleOptMessage { + string string_value = 1; +} + +message ExampleOptOneof { + oneof oneof_fields_1 { + EmptyMessage oneof_empty_message_1 = 1; + Message oneof_message_2 = 2; + } + message EmptyMessage {} + message Message { + string string_value = 1; + } } diff --git a/internal/examples/proto/gen/go/einride/bigquery/example/v1/example_optional.pb.go b/internal/examples/proto/gen/go/einride/bigquery/example/v1/example_optional.pb.go index 41e54f3..4dcd3ce 100644 --- a/internal/examples/proto/gen/go/einride/bigquery/example/v1/example_optional.pb.go +++ b/internal/examples/proto/gen/go/einride/bigquery/example/v1/example_optional.pb.go @@ -25,7 +25,9 @@ type ExampleOptional struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Opt *float64 `protobuf:"fixed64,1,opt,name=opt,proto3,oneof" json:"opt,omitempty"` + OptDouble_1 *float64 `protobuf:"fixed64,1,opt,name=opt_double_1,json=optDouble1,proto3,oneof" json:"opt_double_1,omitempty"` + OptMessage_2 *ExampleOptMessage `protobuf:"bytes,2,opt,name=opt_message_2,json=optMessage2,proto3,oneof" json:"opt_message_2,omitempty"` + OptOneofMessage_3 *ExampleOptOneof `protobuf:"bytes,3,opt,name=opt_oneof_message_3,json=optOneofMessage3,proto3,oneof" json:"opt_oneof_message_3,omitempty"` } func (x *ExampleOptional) Reset() { @@ -60,13 +62,240 @@ func (*ExampleOptional) Descriptor() ([]byte, []int) { return file_einride_bigquery_example_v1_example_optional_proto_rawDescGZIP(), []int{0} } -func (x *ExampleOptional) GetOpt() float64 { - if x != nil && x.Opt != nil { - return *x.Opt +func (x *ExampleOptional) GetOptDouble_1() float64 { + if x != nil && x.OptDouble_1 != nil { + return *x.OptDouble_1 } return 0 } +func (x *ExampleOptional) GetOptMessage_2() *ExampleOptMessage { + if x != nil { + return x.OptMessage_2 + } + return nil +} + +func (x *ExampleOptional) GetOptOneofMessage_3() *ExampleOptOneof { + if x != nil { + return x.OptOneofMessage_3 + } + return nil +} + +type ExampleOptMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3" json:"string_value,omitempty"` +} + +func (x *ExampleOptMessage) Reset() { + *x = ExampleOptMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExampleOptMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExampleOptMessage) ProtoMessage() {} + +func (x *ExampleOptMessage) ProtoReflect() protoreflect.Message { + mi := &file_einride_bigquery_example_v1_example_optional_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 ExampleOptMessage.ProtoReflect.Descriptor instead. +func (*ExampleOptMessage) Descriptor() ([]byte, []int) { + return file_einride_bigquery_example_v1_example_optional_proto_rawDescGZIP(), []int{1} +} + +func (x *ExampleOptMessage) GetStringValue() string { + if x != nil { + return x.StringValue + } + return "" +} + +type ExampleOptOneof struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to OneofFields_1: + // + // *ExampleOptOneof_OneofEmptyMessage_1 + // *ExampleOptOneof_OneofMessage_2 + OneofFields_1 isExampleOptOneof_OneofFields_1 `protobuf_oneof:"oneof_fields_1"` +} + +func (x *ExampleOptOneof) Reset() { + *x = ExampleOptOneof{} + if protoimpl.UnsafeEnabled { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExampleOptOneof) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExampleOptOneof) ProtoMessage() {} + +func (x *ExampleOptOneof) ProtoReflect() protoreflect.Message { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[2] + 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 ExampleOptOneof.ProtoReflect.Descriptor instead. +func (*ExampleOptOneof) Descriptor() ([]byte, []int) { + return file_einride_bigquery_example_v1_example_optional_proto_rawDescGZIP(), []int{2} +} + +func (m *ExampleOptOneof) GetOneofFields_1() isExampleOptOneof_OneofFields_1 { + if m != nil { + return m.OneofFields_1 + } + return nil +} + +func (x *ExampleOptOneof) GetOneofEmptyMessage_1() *ExampleOptOneof_EmptyMessage { + if x, ok := x.GetOneofFields_1().(*ExampleOptOneof_OneofEmptyMessage_1); ok { + return x.OneofEmptyMessage_1 + } + return nil +} + +func (x *ExampleOptOneof) GetOneofMessage_2() *ExampleOptOneof_Message { + if x, ok := x.GetOneofFields_1().(*ExampleOptOneof_OneofMessage_2); ok { + return x.OneofMessage_2 + } + return nil +} + +type isExampleOptOneof_OneofFields_1 interface { + isExampleOptOneof_OneofFields_1() +} + +type ExampleOptOneof_OneofEmptyMessage_1 struct { + OneofEmptyMessage_1 *ExampleOptOneof_EmptyMessage `protobuf:"bytes,1,opt,name=oneof_empty_message_1,json=oneofEmptyMessage1,proto3,oneof"` +} + +type ExampleOptOneof_OneofMessage_2 struct { + OneofMessage_2 *ExampleOptOneof_Message `protobuf:"bytes,2,opt,name=oneof_message_2,json=oneofMessage2,proto3,oneof"` +} + +func (*ExampleOptOneof_OneofEmptyMessage_1) isExampleOptOneof_OneofFields_1() {} + +func (*ExampleOptOneof_OneofMessage_2) isExampleOptOneof_OneofFields_1() {} + +type ExampleOptOneof_EmptyMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ExampleOptOneof_EmptyMessage) Reset() { + *x = ExampleOptOneof_EmptyMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExampleOptOneof_EmptyMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExampleOptOneof_EmptyMessage) ProtoMessage() {} + +func (x *ExampleOptOneof_EmptyMessage) ProtoReflect() protoreflect.Message { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[3] + 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 ExampleOptOneof_EmptyMessage.ProtoReflect.Descriptor instead. +func (*ExampleOptOneof_EmptyMessage) Descriptor() ([]byte, []int) { + return file_einride_bigquery_example_v1_example_optional_proto_rawDescGZIP(), []int{2, 0} +} + +type ExampleOptOneof_Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3" json:"string_value,omitempty"` +} + +func (x *ExampleOptOneof_Message) Reset() { + *x = ExampleOptOneof_Message{} + if protoimpl.UnsafeEnabled { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExampleOptOneof_Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExampleOptOneof_Message) ProtoMessage() {} + +func (x *ExampleOptOneof_Message) ProtoReflect() protoreflect.Message { + mi := &file_einride_bigquery_example_v1_example_optional_proto_msgTypes[4] + 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 ExampleOptOneof_Message.ProtoReflect.Descriptor instead. +func (*ExampleOptOneof_Message) Descriptor() ([]byte, []int) { + return file_einride_bigquery_example_v1_example_optional_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *ExampleOptOneof_Message) GetStringValue() string { + if x != nil { + return x.StringValue + } + return "" +} + var File_einride_bigquery_example_v1_example_optional_proto protoreflect.FileDescriptor var file_einride_bigquery_example_v1_example_optional_proto_rawDesc = []byte{ @@ -75,29 +304,68 @@ var file_einride_bigquery_example_v1_example_optional_proto_rawDesc = []byte{ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, - 0x31, 0x22, 0x30, 0x0a, 0x0f, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x15, 0x0a, 0x03, 0x6f, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x01, 0x48, 0x00, 0x52, 0x03, 0x6f, 0x70, 0x74, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, - 0x6f, 0x70, 0x74, 0x42, 0xab, 0x02, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x65, 0x69, 0x6e, 0x72, - 0x69, 0x64, 0x65, 0x2e, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x14, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x63, 0x67, 0x6f, 0x2e, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x74, 0x65, 0x63, 0x68, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2d, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x65, - 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2f, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, - 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x45, 0x42, 0x45, 0xaa, 0x02, 0x1b, 0x45, 0x69, 0x6e, - 0x72, 0x69, 0x64, 0x65, 0x2e, 0x42, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1b, 0x45, 0x69, 0x6e, 0x72, 0x69, - 0x64, 0x65, 0x5c, 0x42, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5c, 0x45, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x27, 0x45, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, - 0x5c, 0x42, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5c, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x1e, 0x45, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x3a, 0x3a, 0x42, 0x69, 0x67, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x3a, 0x3a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0x22, 0xae, 0x02, 0x0a, 0x0f, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x25, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x5f, 0x64, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x5f, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0a, 0x6f, + 0x70, 0x74, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x31, 0x88, 0x01, 0x01, 0x12, 0x57, 0x0a, 0x0d, + 0x6f, 0x70, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x32, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x62, 0x69, + 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x48, 0x01, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x32, 0x88, 0x01, 0x01, 0x12, 0x60, 0x0a, 0x13, 0x6f, 0x70, 0x74, 0x5f, 0x6f, 0x6e, 0x65, + 0x6f, 0x66, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x33, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x62, 0x69, 0x67, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x4f, 0x6e, 0x65, 0x6f, 0x66, + 0x48, 0x02, 0x52, 0x10, 0x6f, 0x70, 0x74, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x33, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6f, 0x70, 0x74, 0x5f, + 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x31, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x6f, 0x70, 0x74, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x32, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x6f, + 0x70, 0x74, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x33, 0x22, 0x36, 0x0a, 0x11, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb1, 0x02, 0x0a, 0x0f, 0x45, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x12, 0x6e, + 0x0a, 0x15, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, + 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x12, 0x6f, 0x6e, 0x65, 0x6f, + 0x66, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x31, 0x12, 0x5e, + 0x0a, 0x0f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, + 0x65, 0x2e, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, + 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, + 0x0d, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x1a, 0x0e, + 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x2c, + 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x10, 0x0a, 0x0e, + 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x5f, 0x31, 0x42, 0xab, + 0x02, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x62, + 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, + 0x76, 0x31, 0x42, 0x14, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x63, 0x67, 0x6f, 0x2e, 0x65, + 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, 0x74, 0x65, 0x63, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2d, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x69, 0x6e, 0x72, 0x69, 0x64, + 0x65, 0x2f, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x45, 0x42, 0x45, 0xaa, 0x02, 0x1b, 0x45, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x2e, + 0x42, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1b, 0x45, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x5c, 0x42, 0x69, + 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5c, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x27, 0x45, 0x69, 0x6e, 0x72, 0x69, 0x64, 0x65, 0x5c, 0x42, 0x69, 0x67, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x5c, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1e, 0x45, 0x69, + 0x6e, 0x72, 0x69, 0x64, 0x65, 0x3a, 0x3a, 0x42, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x3a, + 0x3a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -112,16 +380,24 @@ func file_einride_bigquery_example_v1_example_optional_proto_rawDescGZIP() []byt return file_einride_bigquery_example_v1_example_optional_proto_rawDescData } -var file_einride_bigquery_example_v1_example_optional_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_einride_bigquery_example_v1_example_optional_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_einride_bigquery_example_v1_example_optional_proto_goTypes = []interface{}{ - (*ExampleOptional)(nil), // 0: einride.bigquery.example.v1.ExampleOptional + (*ExampleOptional)(nil), // 0: einride.bigquery.example.v1.ExampleOptional + (*ExampleOptMessage)(nil), // 1: einride.bigquery.example.v1.ExampleOptMessage + (*ExampleOptOneof)(nil), // 2: einride.bigquery.example.v1.ExampleOptOneof + (*ExampleOptOneof_EmptyMessage)(nil), // 3: einride.bigquery.example.v1.ExampleOptOneof.EmptyMessage + (*ExampleOptOneof_Message)(nil), // 4: einride.bigquery.example.v1.ExampleOptOneof.Message } var file_einride_bigquery_example_v1_example_optional_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: einride.bigquery.example.v1.ExampleOptional.opt_message_2:type_name -> einride.bigquery.example.v1.ExampleOptMessage + 2, // 1: einride.bigquery.example.v1.ExampleOptional.opt_oneof_message_3:type_name -> einride.bigquery.example.v1.ExampleOptOneof + 3, // 2: einride.bigquery.example.v1.ExampleOptOneof.oneof_empty_message_1:type_name -> einride.bigquery.example.v1.ExampleOptOneof.EmptyMessage + 4, // 3: einride.bigquery.example.v1.ExampleOptOneof.oneof_message_2:type_name -> einride.bigquery.example.v1.ExampleOptOneof.Message + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_einride_bigquery_example_v1_example_optional_proto_init() } @@ -142,15 +418,67 @@ func file_einride_bigquery_example_v1_example_optional_proto_init() { return nil } } + file_einride_bigquery_example_v1_example_optional_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExampleOptMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_einride_bigquery_example_v1_example_optional_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExampleOptOneof); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_einride_bigquery_example_v1_example_optional_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExampleOptOneof_EmptyMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_einride_bigquery_example_v1_example_optional_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExampleOptOneof_Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_einride_bigquery_example_v1_example_optional_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_einride_bigquery_example_v1_example_optional_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*ExampleOptOneof_OneofEmptyMessage_1)(nil), + (*ExampleOptOneof_OneofMessage_2)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_einride_bigquery_example_v1_example_optional_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptional.json b/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptional.json index f27507e..86b8e04 100644 --- a/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptional.json +++ b/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptional.json @@ -1,7 +1,38 @@ [ { - "name": "opt", + "name": "opt_double_1", "type": "FLOAT", "mode": "NULLABLE" + }, + { + "name": "opt_message_2", + "type": "RECORD", + "mode": "NULLABLE", + "fields": [ + { + "name": "string_value", + "type": "STRING", + "mode": "NULLABLE" + } + ] + }, + { + "name": "opt_oneof_message_3", + "type": "RECORD", + "mode": "NULLABLE", + "fields": [ + { + "name": "oneof_message_2", + "type": "RECORD", + "mode": "NULLABLE", + "fields": [ + { + "name": "string_value", + "type": "STRING", + "mode": "NULLABLE" + } + ] + } + ] } ] diff --git a/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptmessage.json b/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptmessage.json new file mode 100644 index 0000000..26dc6d2 --- /dev/null +++ b/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptmessage.json @@ -0,0 +1,7 @@ +[ + { + "name": "string_value", + "type": "STRING", + "mode": "NULLABLE" + } +] diff --git a/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptoneof.json b/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptoneof.json new file mode 100644 index 0000000..6ebfded --- /dev/null +++ b/internal/examples/proto/gen/json/einride_bigquery_example_v1_exampleoptoneof.json @@ -0,0 +1,14 @@ +[ + { + "name": "oneof_message_2", + "type": "RECORD", + "mode": "NULLABLE", + "fields": [ + { + "name": "string_value", + "type": "STRING", + "mode": "NULLABLE" + } + ] + } +]