Why the default implementation of foo.pb.go use global registry, can I modify it to avoid namesapce conflict?
21:40 08 Jul 2024

From the official doc says. It will meet a namespace conflict if I have a single proto file and using it generated two pb in different pkg. For example, example.proto is generate into two example.pb.go in pkg1 and pkg2 separately.

├─test_proto
    ├─main.go
    ├─example.proto
    ├─pkg1
       ├─example
           ├─example.pb.go
    ├─pkg2
       ├─example
           ├─example.pb.go

example.proto

syntax = "proto3";

package example;
option go_package = "./example";

message Greeting {
  string first_name = 1;
  string last_name = 2;
}

The command I use:

protoc --go_out=./pkg1 -I=. example.proto
protoc --go_out=./pkg2 -I=. example.proto

main.go

package main

import (
    "fmt"

    "Hello/test_proto/pkg1/example"
    pkg2proto "Hello/test_proto/pkg2/example"
)

func main() {
    pkg1Greeting := example.Greeting{FirstName: "foo"}
    pkg2Greeting := pkg2proto.Greeting{FirstName: "bar"}

    fmt.Println(pkg1Greeting.FirstName, pkg2Greeting.FirstName)
}

Now if I run main.go. It will panic with namespace conflict.

Exception has occurred: panic
"proto:\u00a0file \"example.proto\" is already registered\n\tprevious...

But if I modify one of the example.pb.go:

import "google.golang.org/protobuf/reflect/protoregistry"

    out := protoimpl.TypeBuilder{
        File: protoimpl.DescBuilder{
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_example_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   1,
            NumExtensions: 0,
            NumServices:   0,
            FileRegistry: new(protoregistry.Files), // add this line
        },
        GoTypes:           file_example_proto_goTypes,
        DependencyIndexes: file_example_proto_depIdxs,
        MessageInfos:      file_example_proto_msgTypes,
        TypeRegistry: new(protoregistry.Types),    // add this line
    }.Build()

Instead using default global FileRegistry and TypeRegistry. If I new a instance for it. The program will run smoothly. So why the default implementation must use the global Registry? Is it okay if I modify it?

go protocol-buffers protocols