mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-04-17 02:42:35 +00:00
This covers most of the TODO around validation. I left open the ones that we didn't have clear consensus on yet. Change-Id: I336c53173ee8d7447558b1e3a0c1ef945e986cd5 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/175140 Reviewed-by: Joe Tsai <joetsai@google.com> Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
576 lines
20 KiB
Go
576 lines
20 KiB
Go
package protodesc
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/golang/protobuf/v2/internal/scalar"
|
|
"github.com/golang/protobuf/v2/reflect/protoregistry"
|
|
|
|
descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
|
|
)
|
|
|
|
// Tests validation logic for malformed descriptors.
|
|
func TestNewFile_ValidationErrors(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
deps []*descriptorpb.FileDescriptorProto
|
|
fd *descriptorpb.FileDescriptorProto
|
|
wantErr string
|
|
}{{
|
|
name: "field number reserved",
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("field-number-reserved.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("BadMessage"),
|
|
ReservedRange: []*descriptorpb.DescriptorProto_ReservedRange{{
|
|
Start: scalar.Int32(3),
|
|
End: scalar.Int32(4),
|
|
}},
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("good_field"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
}, {
|
|
Name: scalar.String("bad_field"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "reserved number 3",
|
|
}, {
|
|
name: "field name reserved",
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("field-name-reserved.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("BadMessage"),
|
|
ReservedName: []string{"bad_field", "baz"},
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("good_field"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
}, {
|
|
Name: scalar.String("bad_field"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: `reserved name "bad_field"`,
|
|
}, {
|
|
name: "normal field with extendee",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("extensible.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("ExtensibleMessage"),
|
|
ExtensionRange: []*descriptorpb.DescriptorProto_ExtensionRange{{
|
|
Start: scalar.Int32(1000),
|
|
End: scalar.Int32(2000),
|
|
}},
|
|
}},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("field-with-extendee.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
Dependency: []string{"extensible.proto"},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("BadMessage"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("good_field"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
}, {
|
|
Name: scalar.String("bad_field"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
Extendee: scalar.String(".foo.ExtensibleMessage"),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "may not have extendee",
|
|
}, {
|
|
name: "type_name on int32 field",
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("int32-with-type-name.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("AnEnum"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("BadMessage"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("good_field"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
}, {
|
|
Name: scalar.String("bad_field"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
|
|
TypeName: scalar.String("AnEnum"),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "type_name",
|
|
}, {
|
|
name: "type_name on string extension",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("extensible.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("ExtensibleMessage"),
|
|
ExtensionRange: []*descriptorpb.DescriptorProto_ExtensionRange{{
|
|
Start: scalar.Int32(1000),
|
|
End: scalar.Int32(2000),
|
|
}},
|
|
}},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("string-ext-with-type-name.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
Dependency: []string{"extensible.proto"},
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("AnEnum"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
Extension: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("my_ext"),
|
|
Number: scalar.Int32(1000),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
Extendee: scalar.String(".foo.ExtensibleMessage"),
|
|
TypeName: scalar.String("AnEnum"),
|
|
}},
|
|
},
|
|
wantErr: "type_name",
|
|
}, {
|
|
name: "oneof_index on extension",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("extensible.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("ExtensibleMessage"),
|
|
ExtensionRange: []*descriptorpb.DescriptorProto_ExtensionRange{{
|
|
Start: scalar.Int32(1000),
|
|
End: scalar.Int32(2000),
|
|
}},
|
|
}},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("ext-with-oneof-index.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
Dependency: []string{"extensible.proto"},
|
|
Extension: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("my_ext"),
|
|
Number: scalar.Int32(1000),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
Extendee: scalar.String(".foo.ExtensibleMessage"),
|
|
OneofIndex: scalar.Int32(0),
|
|
}},
|
|
},
|
|
wantErr: "oneof_index",
|
|
}, {
|
|
name: "enum with reserved number",
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("enum-with-reserved-number.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("AnEnum"),
|
|
ReservedRange: []*descriptorpb.EnumDescriptorProto_EnumReservedRange{{
|
|
Start: scalar.Int32(5),
|
|
End: scalar.Int32(6),
|
|
}, {
|
|
Start: scalar.Int32(10),
|
|
End: scalar.Int32(12),
|
|
}},
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}, {
|
|
Name: scalar.String("FOO"),
|
|
Number: scalar.Int32(1),
|
|
}, {
|
|
Name: scalar.String("BAR"),
|
|
Number: scalar.Int32(2),
|
|
}, {
|
|
Name: scalar.String("BAD"),
|
|
Number: scalar.Int32(11),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "reserved number 11",
|
|
}, {
|
|
name: "enum with reserved number",
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("enum-with-reserved-name.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("ParentMessage"),
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("AnEnum"),
|
|
ReservedName: []string{"ABC", "XYZ"},
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}, {
|
|
Name: scalar.String("FOO"),
|
|
Number: scalar.Int32(1),
|
|
}, {
|
|
Name: scalar.String("BAR"),
|
|
Number: scalar.Int32(2),
|
|
}, {
|
|
Name: scalar.String("XYZ"),
|
|
Number: scalar.Int32(3),
|
|
}},
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: `reserved name "XYZ"`,
|
|
}, {
|
|
name: "message dependency without import",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("foo.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Foo"),
|
|
}},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("message-dependency-without-import.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Bar"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("id"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
}, {
|
|
Name: scalar.String("foo"),
|
|
Number: scalar.Int32(2),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
|
|
TypeName: scalar.String(".foo.Foo"),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "foo.Foo without import of foo.proto",
|
|
}, {
|
|
name: "enum dependency without import",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("foo.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("Foo"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("enum-dependency-without-import.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Bar"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("id"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
}, {
|
|
Name: scalar.String("foo"),
|
|
Number: scalar.Int32(2),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
|
|
TypeName: scalar.String(".foo.Foo"),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "foo.Foo without import of foo.proto",
|
|
}, {
|
|
name: "message dependency on without import on file imported by a public import",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("foo.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Foo"),
|
|
}},
|
|
}, {
|
|
Name: scalar.String("baz.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
Dependency: []string{"foo.proto"},
|
|
}, {
|
|
Name: scalar.String("old-baz.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
Dependency: []string{"baz.proto"},
|
|
PublicDependency: []int32{0},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("message-dependency-without-import.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
Dependency: []string{"old-baz.proto"},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Bar"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("id"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
}, {
|
|
Name: scalar.String("foo"),
|
|
Number: scalar.Int32(2),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
|
|
TypeName: scalar.String(".foo.Foo"),
|
|
}},
|
|
}},
|
|
},
|
|
wantErr: "foo.Foo without import of foo.proto",
|
|
}}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
r := new(protoregistry.Files)
|
|
for _, dep := range tc.deps {
|
|
f, err := NewFile(dep, r)
|
|
if err != nil {
|
|
t.Fatalf("Error creating dependency: %v", err)
|
|
}
|
|
if err := r.Register(f); err != nil {
|
|
t.Fatalf("Error adding dependency: %v", err)
|
|
}
|
|
}
|
|
if _, err := NewFile(tc.fd, r); err == nil || !strings.Contains(err.Error(), tc.wantErr) {
|
|
t.Errorf("NewFile: got err = %v; want error containing %q", err, tc.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Sanity checks for well-formed descriptors. Most behavior with well-formed descriptors is covered
|
|
// by other tests that rely on generated descriptors.
|
|
func TestNewFile_ValidationOK(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
deps []*descriptorpb.FileDescriptorProto
|
|
fd *descriptorpb.FileDescriptorProto
|
|
}{{
|
|
name: "self contained file",
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("self-contained.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("TopLevelEnum"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("TopLevelMessage"),
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("NestedEnum"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
NestedType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("NestedMessage"),
|
|
}},
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("id"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
}, {
|
|
Name: scalar.String("top_level_enum"),
|
|
Number: scalar.Int32(2),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
|
|
TypeName: scalar.String(".foo.TopLevelEnum"),
|
|
}, {
|
|
Name: scalar.String("nested_enum"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
|
|
TypeName: scalar.String(".foo.TopLevelMessage.NestedEnum"),
|
|
}, {
|
|
Name: scalar.String("nested_message"),
|
|
Number: scalar.Int32(4),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
|
|
TypeName: scalar.String(".foo.TopLevelMessage.NestedMessage"),
|
|
}},
|
|
}},
|
|
},
|
|
}, {
|
|
name: "external types with explicit import",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("foo.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("FooMessage"),
|
|
}},
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("BarEnum"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("external-types-with-explicit-import.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
Dependency: []string{"foo.proto"},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Bar"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("id"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
}, {
|
|
Name: scalar.String("foo"),
|
|
Number: scalar.Int32(2),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
|
|
TypeName: scalar.String(".foo.FooMessage"),
|
|
}, {
|
|
Name: scalar.String("bar"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
|
|
TypeName: scalar.String(".foo.BarEnum"),
|
|
}},
|
|
}},
|
|
},
|
|
}, {
|
|
name: "external types with transitive public imports",
|
|
deps: []*descriptorpb.FileDescriptorProto{{
|
|
Name: scalar.String("quux.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("QuuxMessage"),
|
|
}},
|
|
}, {
|
|
Name: scalar.String("foo.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
Dependency: []string{"quux.proto"},
|
|
PublicDependency: []int32{0},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("FooMessage"),
|
|
}},
|
|
EnumType: []*descriptorpb.EnumDescriptorProto{{
|
|
Name: scalar.String("BarEnum"),
|
|
Value: []*descriptorpb.EnumValueDescriptorProto{{
|
|
Name: scalar.String("UNKNOWN"),
|
|
Number: scalar.Int32(0),
|
|
}},
|
|
}},
|
|
}, {
|
|
Name: scalar.String("old-name.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("foo"),
|
|
Dependency: []string{"foo.proto"},
|
|
PublicDependency: []int32{0},
|
|
}},
|
|
fd: &descriptorpb.FileDescriptorProto{
|
|
Name: scalar.String("external-types-with-public-import.proto"),
|
|
Syntax: scalar.String("proto2"),
|
|
Package: scalar.String("bar"),
|
|
Dependency: []string{"old-name.proto"},
|
|
MessageType: []*descriptorpb.DescriptorProto{{
|
|
Name: scalar.String("Bar"),
|
|
Field: []*descriptorpb.FieldDescriptorProto{{
|
|
Name: scalar.String("id"),
|
|
Number: scalar.Int32(1),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
|
|
}, {
|
|
Name: scalar.String("foo"),
|
|
Number: scalar.Int32(2),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
|
|
TypeName: scalar.String(".foo.FooMessage"),
|
|
}, {
|
|
Name: scalar.String("bar"),
|
|
Number: scalar.Int32(3),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
|
|
TypeName: scalar.String(".foo.BarEnum"),
|
|
}, {
|
|
Name: scalar.String("quux"),
|
|
Number: scalar.Int32(4),
|
|
Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
|
|
Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
|
|
TypeName: scalar.String(".foo.QuuxMessage"),
|
|
}},
|
|
}},
|
|
},
|
|
}}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
r := new(protoregistry.Files)
|
|
for _, dep := range tc.deps {
|
|
f, err := NewFile(dep, r)
|
|
if err != nil {
|
|
t.Fatalf("Error creating dependency: %v", err)
|
|
}
|
|
if err := r.Register(f); err != nil {
|
|
t.Fatalf("Error adding dependency: %v", err)
|
|
}
|
|
}
|
|
if _, err := NewFile(tc.fd, r); err != nil {
|
|
t.Errorf("NewFile: got err = %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|