|  | // Copyright 2023 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package dynamicpb_test | 
|  |  | 
|  | import ( | 
|  | "strings" | 
|  | "testing" | 
|  |  | 
|  | "google.golang.org/protobuf/reflect/protoreflect" | 
|  | "google.golang.org/protobuf/reflect/protoregistry" | 
|  | "google.golang.org/protobuf/types/descriptorpb" | 
|  | "google.golang.org/protobuf/types/dynamicpb" | 
|  |  | 
|  | registrypb "google.golang.org/protobuf/internal/testprotos/registry" | 
|  | ) | 
|  |  | 
|  | var _ protoregistry.ExtensionTypeResolver = &dynamicpb.Types{} | 
|  | var _ protoregistry.MessageTypeResolver = &dynamicpb.Types{} | 
|  |  | 
|  | func newTestTypes() *dynamicpb.Types { | 
|  | files := &protoregistry.Files{} | 
|  | files.RegisterFile(registrypb.File_internal_testprotos_registry_test_proto) | 
|  | return dynamicpb.NewTypes(files) | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesTypeMismatch(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | const messageName = "testprotos.Message1" | 
|  | const enumName = "testprotos.Enum1" | 
|  |  | 
|  | _, err := types.FindEnumByName(messageName) | 
|  | want := "found wrong type: got message, want enum" | 
|  | if err == nil || !strings.Contains(err.Error(), want) { | 
|  | t.Errorf("types.FindEnumByName(%q) = _, %q, want %q", messageName, err, want) | 
|  | } | 
|  |  | 
|  | _, err = types.FindMessageByName(enumName) | 
|  | want = "found wrong type: got enum, want message" | 
|  | if err == nil || !strings.Contains(err.Error(), want) { | 
|  | t.Errorf("types.FindMessageByName(%q) = _, %q, want %q", messageName, err, want) | 
|  | } | 
|  |  | 
|  | _, err = types.FindExtensionByName(enumName) | 
|  | want = "found wrong type: got enum, want extension" | 
|  | if err == nil || !strings.Contains(err.Error(), want) { | 
|  | t.Errorf("types.FindExtensionByName(%q) = _, %q, want %q", messageName, err, want) | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesEnumNotFound(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | for _, name := range []protoreflect.FullName{ | 
|  | "Enum1", | 
|  | "testprotos.DoesNotExist", | 
|  | } { | 
|  | _, err := types.FindEnumByName(name) | 
|  | if err != protoregistry.NotFound { | 
|  | t.Errorf("types.FindEnumByName(%q) = _, %v; want protoregistry.NotFound", name, err) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesFindEnumByName(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | name := protoreflect.FullName("testprotos.Enum1") | 
|  | et, err := types.FindEnumByName(name) | 
|  | if err != nil { | 
|  | t.Fatalf("types.FindEnumByName(%q) = %v", name, err) | 
|  | } | 
|  | if got, want := et.Descriptor().FullName(), name; got != want { | 
|  | t.Fatalf("types.FindEnumByName(%q).Descriptor().FullName() = %q, want %q", name, got, want) | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesMessageNotFound(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | for _, name := range []protoreflect.FullName{ | 
|  | "Message1", | 
|  | "testprotos.DoesNotExist", | 
|  | } { | 
|  | _, err := types.FindMessageByName(name) | 
|  | if err != protoregistry.NotFound { | 
|  | t.Errorf("types.FindMessageByName(%q) = _, %v; want protoregistry.NotFound", name, err) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesFindMessageByName(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | name := protoreflect.FullName("testprotos.Message1") | 
|  | mt, err := types.FindMessageByName(name) | 
|  | if err != nil { | 
|  | t.Fatalf("types.FindMessageByName(%q) = %v", name, err) | 
|  | } | 
|  | if got, want := mt.Descriptor().FullName(), name; got != want { | 
|  | t.Fatalf("types.FindMessageByName(%q).Descriptor().FullName() = %q, want %q", name, got, want) | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesExtensionNotFound(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | for _, name := range []protoreflect.FullName{ | 
|  | "string_field", | 
|  | "testprotos.DoesNotExist", | 
|  | } { | 
|  | _, err := types.FindExtensionByName(name) | 
|  | if err != protoregistry.NotFound { | 
|  | t.Errorf("types.FindExtensionByName(%q) = _, %v; want protoregistry.NotFound", name, err) | 
|  | } | 
|  | } | 
|  | messageName := protoreflect.FullName("testprotos.Message1") | 
|  | if _, err := types.FindExtensionByNumber(messageName, 100); err != protoregistry.NotFound { | 
|  | t.Errorf("types.FindExtensionByNumber(%q, 100) = _, %v; want protoregistry.NotFound", messageName, 100) | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesFindExtensionByNameOrNumber(t *testing.T) { | 
|  | types := newTestTypes() | 
|  | messageName := protoreflect.FullName("testprotos.Message1") | 
|  | mt, err := types.FindMessageByName(messageName) | 
|  | if err != nil { | 
|  | t.Fatalf("types.FindMessageByName(%q) = %v", messageName, err) | 
|  | } | 
|  | for _, extensionName := range []protoreflect.FullName{ | 
|  | "testprotos.string_field", | 
|  | "testprotos.Message4.message_field", | 
|  | } { | 
|  | xt, err := types.FindExtensionByName(extensionName) | 
|  | if err != nil { | 
|  | t.Fatalf("types.FindExtensionByName(%q) = %v", extensionName, err) | 
|  | } | 
|  | if got, want := xt.TypeDescriptor().FullName(), extensionName; got != want { | 
|  | t.Fatalf("types.FindExtensionByName(%q).TypeDescriptor().FullName() = %q, want %q", extensionName, got, want) | 
|  | } | 
|  | if got, want := xt.TypeDescriptor().ContainingMessage(), mt.Descriptor(); got != want { | 
|  | t.Fatalf("xt.TypeDescriptor().ContainingMessage() = %q, want %q", got.FullName(), want.FullName()) | 
|  | } | 
|  | number := xt.TypeDescriptor().Number() | 
|  | xt2, err := types.FindExtensionByNumber(messageName, number) | 
|  | if err != nil { | 
|  | t.Fatalf("types.FindExtensionByNumber(%q, %v) = %v", messageName, number, err) | 
|  | } | 
|  | if xt != xt2 { | 
|  | t.Fatalf("FindExtensionByName returned a differet extension than FindExtensionByNumber") | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestDynamicTypesFilesChangeAfterCreation(t *testing.T) { | 
|  | files := &protoregistry.Files{} | 
|  | files.RegisterFile(descriptorpb.File_google_protobuf_descriptor_proto) | 
|  | types := dynamicpb.NewTypes(files) | 
|  |  | 
|  | // Not found: Files registry does not contain this file. | 
|  | const message = "testprotos.Message1" | 
|  | const number = 11 | 
|  | if _, err := types.FindMessageByName(message); err != protoregistry.NotFound { | 
|  | t.Errorf("types.FindMessageByName(%q) = %v, want protoregistry.NotFound", message, err) | 
|  | } | 
|  | if _, err := types.FindExtensionByNumber(message, number); err != protoregistry.NotFound { | 
|  | t.Errorf("types.FindExtensionByNumber(%q, %v) = %v, want protoregistry.NotFound", message, number, err) | 
|  | } | 
|  |  | 
|  | // Found: Add the file to the registry and recheck. | 
|  | files.RegisterFile(registrypb.File_internal_testprotos_registry_test_proto) | 
|  | if _, err := types.FindMessageByName(message); err != nil { | 
|  | t.Errorf("types.FindMessageByName(%q) = %v, want nil", message, err) | 
|  | } | 
|  | if _, err := types.FindExtensionByNumber(message, number); err != nil { | 
|  | t.Errorf("types.FindExtensionByNumber(%q, %v) = %v, want nil", message, number, err) | 
|  | } | 
|  | } |