diff --git a/bigquery/storage/managedwriter/adapt/protoconversion.go b/bigquery/storage/managedwriter/adapt/protoconversion.go index 27526dd10e9a..84b3f2ac487e 100644 --- a/bigquery/storage/managedwriter/adapt/protoconversion.go +++ b/bigquery/storage/managedwriter/adapt/protoconversion.go @@ -291,7 +291,8 @@ func tableFieldSchemaToFieldDescriptorProto(field *storagepb.TableFieldSchema, i // and not the namespaces when decoding, this is sufficient for the needs of the API's representation. // // In addition to nesting messages, this method also handles some encapsulation of enum types to avoid possible -// conflicts due to ambiguities. +// conflicts due to ambiguities, and clears oneof indices as oneof isn't a concept that maps into BigQuery +// schemas. func NormalizeDescriptor(in protoreflect.MessageDescriptor) (*descriptorpb.DescriptorProto, error) { return normalizeDescriptorInternal(in, newStringSet(), newStringSet(), newStringSet(), nil) } @@ -310,6 +311,9 @@ func normalizeDescriptorInternal(in protoreflect.MessageDescriptor, visitedTypes for i := 0; i < in.Fields().Len(); i++ { inField := in.Fields().Get(i) resultFDP := protodesc.ToFieldDescriptorProto(inField) + if resultFDP.OneofIndex != nil { + resultFDP.OneofIndex = nil + } if inField.Kind() == protoreflect.MessageKind || inField.Kind() == protoreflect.GroupKind { // Handle fields that reference messages. // Groups are a proto2-ism which predated nested messages. diff --git a/bigquery/storage/managedwriter/adapt/protoconversion_test.go b/bigquery/storage/managedwriter/adapt/protoconversion_test.go index d72041c34c69..21ef4dfd06a6 100644 --- a/bigquery/storage/managedwriter/adapt/protoconversion_test.go +++ b/bigquery/storage/managedwriter/adapt/protoconversion_test.go @@ -591,6 +591,36 @@ func TestNormalizeDescriptor(t *testing.T) { }, }, }, + { + description: "WithOneOf", + in: (&testdata.WithOneOf{}).ProtoReflect().Descriptor(), + want: &descriptorpb.DescriptorProto{ + Name: proto.String("testdata_WithOneOf"), + Field: []*descriptorpb.FieldDescriptorProto{ + { + Name: proto.String("int32_value"), + JsonName: proto.String("int32Value"), + Number: proto.Int32(1), + Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(), + Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(), + }, + { + Name: proto.String("string_value"), + JsonName: proto.String("stringValue"), + Number: proto.Int32(2), + Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(), + Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(), + }, + { + Name: proto.String("double_value"), + JsonName: proto.String("doubleValue"), + Number: proto.Int32(3), + Type: descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(), + Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(), + }, + }, + }, + }, } for _, tc := range testCases { diff --git a/bigquery/storage/managedwriter/testdata/testing.pb.go b/bigquery/storage/managedwriter/testdata/testing.pb.go index 6fea5686c152..75ae418b7d4c 100644 --- a/bigquery/storage/managedwriter/testdata/testing.pb.go +++ b/bigquery/storage/managedwriter/testdata/testing.pb.go @@ -572,6 +572,94 @@ func (x *RecursiveTypeTopMessage) GetField() *RecursiveTypeTopMessage { return nil } +type WithOneOf struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Int32Value *int32 `protobuf:"varint,1,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"` + // Types that are assignable to OneofValue: + // *WithOneOf_StringValue + // *WithOneOf_DoubleValue + OneofValue isWithOneOf_OneofValue `protobuf_oneof:"oneof_value"` +} + +func (x *WithOneOf) Reset() { + *x = WithOneOf{} + if protoimpl.UnsafeEnabled { + mi := &file_testing_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WithOneOf) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WithOneOf) ProtoMessage() {} + +func (x *WithOneOf) ProtoReflect() protoreflect.Message { + mi := &file_testing_proto_msgTypes[8] + 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 WithOneOf.ProtoReflect.Descriptor instead. +func (*WithOneOf) Descriptor() ([]byte, []int) { + return file_testing_proto_rawDescGZIP(), []int{8} +} + +func (x *WithOneOf) GetInt32Value() int32 { + if x != nil && x.Int32Value != nil { + return *x.Int32Value + } + return 0 +} + +func (m *WithOneOf) GetOneofValue() isWithOneOf_OneofValue { + if m != nil { + return m.OneofValue + } + return nil +} + +func (x *WithOneOf) GetStringValue() string { + if x, ok := x.GetOneofValue().(*WithOneOf_StringValue); ok { + return x.StringValue + } + return "" +} + +func (x *WithOneOf) GetDoubleValue() float64 { + if x, ok := x.GetOneofValue().(*WithOneOf_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +type isWithOneOf_OneofValue interface { + isWithOneOf_OneofValue() +} + +type WithOneOf_StringValue struct { + StringValue string `protobuf:"bytes,2,opt,name=string_value,json=stringValue,oneof"` +} + +type WithOneOf_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue,oneof"` +} + +func (*WithOneOf_StringValue) isWithOneOf_OneofValue() {} + +func (*WithOneOf_DoubleValue) isWithOneOf_OneofValue() {} + var File_testing_proto protoreflect.FileDescriptor var file_testing_proto_rawDesc = []byte{ @@ -645,13 +733,22 @@ var file_testing_proto_rawDesc = []byte{ 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x54, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x2a, 0x28, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x75, 0x6d, - 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x30, 0x10, 0x00, 0x12, - 0x0d, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x31, 0x10, 0x01, 0x42, 0x3d, - 0x5a, 0x3b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x62, 0x69, 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, + 0x69, 0x65, 0x6c, 0x64, 0x22, 0x85, 0x01, 0x0a, 0x09, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x6e, 0x65, + 0x4f, 0x66, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, + 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0d, 0x0a, + 0x0b, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x28, 0x0a, 0x08, + 0x54, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, + 0x45, 0x6e, 0x75, 0x6d, 0x30, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x45, + 0x6e, 0x75, 0x6d, 0x31, 0x10, 0x01, 0x42, 0x3d, 0x5a, 0x3b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x62, 0x69, + 0x67, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, + 0x74, 0x64, 0x61, 0x74, 0x61, } var ( @@ -667,7 +764,7 @@ func file_testing_proto_rawDescGZIP() []byte { } var file_testing_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_testing_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_testing_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_testing_proto_goTypes = []interface{}{ (TestEnum)(0), // 0: testdata.TestEnum (*AllSupportedTypes)(nil), // 1: testdata.AllSupportedTypes @@ -678,13 +775,14 @@ var file_testing_proto_goTypes = []interface{}{ (*ContainsRecursive)(nil), // 6: testdata.ContainsRecursive (*RecursiveType)(nil), // 7: testdata.RecursiveType (*RecursiveTypeTopMessage)(nil), // 8: testdata.RecursiveTypeTopMessage - (*wrapperspb.Int64Value)(nil), // 9: google.protobuf.Int64Value - (*wrapperspb.StringValue)(nil), // 10: google.protobuf.StringValue + (*WithOneOf)(nil), // 9: testdata.WithOneOf + (*wrapperspb.Int64Value)(nil), // 10: google.protobuf.Int64Value + (*wrapperspb.StringValue)(nil), // 11: google.protobuf.StringValue } var file_testing_proto_depIdxs = []int32{ 0, // 0: testdata.AllSupportedTypes.enum_value:type_name -> testdata.TestEnum - 9, // 1: testdata.WithWellKnownTypes.wrapped_int64:type_name -> google.protobuf.Int64Value - 10, // 2: testdata.WithWellKnownTypes.wrapped_string:type_name -> google.protobuf.StringValue + 10, // 1: testdata.WithWellKnownTypes.wrapped_int64:type_name -> google.protobuf.Int64Value + 11, // 2: testdata.WithWellKnownTypes.wrapped_string:type_name -> google.protobuf.StringValue 3, // 3: testdata.NestedType.inner_type:type_name -> testdata.InnerType 4, // 4: testdata.ComplexType.nested_repeated_type:type_name -> testdata.NestedType 3, // 5: testdata.ComplexType.inner_type:type_name -> testdata.InnerType @@ -800,6 +898,22 @@ func file_testing_proto_init() { return nil } } + file_testing_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WithOneOf); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_testing_proto_msgTypes[8].OneofWrappers = []interface{}{ + (*WithOneOf_StringValue)(nil), + (*WithOneOf_DoubleValue)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -807,7 +921,7 @@ func file_testing_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_testing_proto_rawDesc, NumEnums: 1, - NumMessages: 8, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, diff --git a/bigquery/storage/managedwriter/testdata/testing.proto b/bigquery/storage/managedwriter/testdata/testing.proto index 3a49245494d2..36f676521309 100644 --- a/bigquery/storage/managedwriter/testdata/testing.proto +++ b/bigquery/storage/managedwriter/testdata/testing.proto @@ -65,4 +65,12 @@ message RecursiveType { message RecursiveTypeTopMessage { optional RecursiveTypeTopMessage field = 2; +} + +message WithOneOf { + optional int32 int32_value = 1; + oneof oneof_value { + string string_value = 2; + double double_value = 3; + } } \ No newline at end of file