Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How could I solve enum conflict? #451

Closed
hanke0 opened this issue Feb 13, 2025 · 3 comments
Closed

How could I solve enum conflict? #451

hanke0 opened this issue Feb 13, 2025 · 3 comments

Comments

@hanke0
Copy link

hanke0 commented Feb 13, 2025

It panics when I compile following proto file.
The message says that panic: foo.proto:11:9: symbol "google.protobuf.UNSPECIFIC" already defined at foo.proto:7:9; protobuf uses C++ scoping rules for enum values, so they exist in the scope enclosing the enum, how could I solve it?

syntax = "proto3";

package google.protobuf;

enum Foo {
	UNSPECIFIC = 0;
}

enum B {
	UNSPECIFIC = 0;
}
package main

import (
	"context"
	"fmt"
	"io"
	"strings"

	"github.com/bufbuild/protocompile"
)

type rd struct {
	*strings.Reader
}

func (rd) Close() error {
	return nil
}

var pb = &rd{
	Reader: strings.NewReader(`
syntax = "proto3";

package google.protobuf;

enum Foo {
	UNSPECIFIC = 0;
}

enum Bar {
	UNSPECIFIC = 0;
}`),
}

func main() {
	comp := protocompile.Compiler{
		Resolver: &protocompile.SourceResolver{
			Accessor: func(path string) (io.ReadCloser, error) {
				return pb, nil
			},
		},
	}
	fs, err := comp.Compile(context.Background(), "foo.proto")
	if err != nil {
		panic(err)
	}
	fmt.Println(fs)
}

@jhump
Copy link
Member

jhump commented Feb 13, 2025

@hanke0, you must rename one or both of the enum values so they don't have the same name. Apologies if the error message is unclear. But it's saying that those enum value names are in the same lexical scope -- so the fully-qualified name for both elements is google.protobuf.UNSPECIFIC. The enclosing enum's name is not part of its full name (which is also how C++ enums work).

Also see this part of the spec: https://protobuf.com/docs/language-spec#fully-qualified-names

@hanke0
Copy link
Author

hanke0 commented Feb 14, 2025

Is there be an option that I can ignore this error and build successful?
It functions properly in protoc-go and generates code:

type Foo int32

const (
	Foo_ UNSPECIFIC  Foo = 0
)

type Bar int32

const (
	Bar_UNSPECIFIC  Foo = 0
)

@jhump

@timostamm
Copy link
Member

@hanke0, the Protobuf source is invalid, and doesn't compile with protoc or buf. To solve the conflict, you'll have to add a prefix to the name:

enum Foo {
  FOO_UNSPECIFIC = 0;
}

enum B {
  B_UNSPECIFIC = 0;
}

If you ignore this error, the Protobuf source won't compile elsewhere, and the compiled descriptors wouldn't be safe to generate code from. Besides C++, there may be other code generators that rely on this limitation to be enforced. So I don't think we want to provide an option to disable the limitation.

It is possible that the limitation will be lifted in a future edition though, see this comment in descriptor.proto.

@timostamm timostamm closed this as not planned Won't fix, can't repro, duplicate, stale Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants