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

IDE indexing broken for go_proto_library with custom compilers #7010

Closed
H5-O5 opened this issue Nov 19, 2024 · 8 comments · Fixed by #7034
Closed

IDE indexing broken for go_proto_library with custom compilers #7010

H5-O5 opened this issue Nov 19, 2024 · 8 comments · Fixed by #7034
Labels
awaiting-maintainer Awaiting review from Bazel team on issues lang: go Go rules integration product: GoLand GoLand plugin type: bug

Comments

@H5-O5
Copy link
Contributor

H5-O5 commented Nov 19, 2024

Description of the bug:

Hi everyone, I wonder if someone could help me with this issue:

I have custom proto plugins, and my BUILD file looks like this:

load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")

proto_library(
    name = "cache_proto",
    srcs = [
        "cache_api.proto",
        "cache_service.proto",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "@com_google_protobuf//:any_proto",
    ],
)

go_proto_library(
    name = "cache_go_proto",
    importpath = "my.example.com/proj/cachepb",
    proto = ":cache_proto",
    visibility = ["//visibility:public"],
)

go_proto_library(
    name = "cache_go_proto_my_plugin",
    compilers = [
        "@my_plugin_repo//foo:my_plugin",
    ],
    importpath = "my.example.com/proj/cachepb/cacheservice",
    proto = ":cache_proto",
    visibility = ["//visibility:public"],
    deps = [
        ":cache_go_proto",
    ],
)

where my_plugin will generate some codes in a different importpath. bazel build is happy (that is, if a target depends on cache_go_proto_my_plugin, it can successfully use the import path without a problem). But GoLand with bazel plugin would only index my.example.com/proj/cachepb but not my.example.com/proj/cachepb/cacheservice.

Interestingly, GoLand shows the import as green text with red wavy underline showing unused import. If I type cacheservice, it pops up completion entries correctly. But if you write foo := cacheservice.SomeFunc(), the SomeFunc() is marked as red. You can't jump to SomeFunc and foo.<TAB> doesn't work.

What could be the problem and how can I debug this?

Which category does this issue belong to?

No response

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Creating an MWE is not easy. Let's see if there are things I could try before I create an MWE.

Which Intellij IDE are you using? Please provide the specific version.

#GO-243.21565.208

What programming languages and tools are you using? Please provide specific versions.

No response

What Bazel plugin version are you using?

tried latest stable version and DEV version

Have you found anything relevant by searching the web?

Nope

Any other information, logs, or outputs that you want to share?

No response

@H5-O5 H5-O5 added awaiting-maintainer Awaiting review from Bazel team on issues type: bug labels Nov 19, 2024
@tpasternak
Copy link
Collaborator

Cc @iliakondratev

@sgowroji sgowroji added product: GoLand GoLand plugin lang: go Go rules integration labels Nov 20, 2024
@H5-O5
Copy link
Contributor Author

H5-O5 commented Nov 20, 2024

I got an update for this:

It seems that the problem is due to // + build ignore. That is:

Let's say @my_plugin_repo//foo:my_plugin claims 6 files, but the protoc-plugin only generates 4 files. The missing 2 files will be generated by "rules_go" containing

// +build ignore

package ignore

Then, getPackageName somehow recognizes this, and return "ignore" as package name.

For the official rules, the package name would be basename(importpath), which is cachepb in this case.

I hacked getPackageName to return basename(importpath) and everything seems to work now. I haven't fully tested it but this is promising.

@iliakondratev
Copy link
Collaborator

Hi @H5-O5, thank you for the details. Would you expect that getPackageName respects the +build ignore flag while resolving packages and falls back to basename(importpath) in this case?

@H5-O5
Copy link
Contributor Author

H5-O5 commented Nov 20, 2024

No. Given that "build ignore" is generated by rules_go, and its name clearly indicates that this package should be ignored, I'd suggest adding this filter:

Edit: I misunderstood. The answer is yes. getPackageName should respect +build ignore instead of package ignore.

@iliakondratev
Copy link
Collaborator

@H5-O5, thank you for your suggestion. While I see where you’re coming from, ignore can be a valid Go package and cause false positives. Filtering out files with the +build ignore tag seems more appropriate and safer in this case, aligning with how build tags are intended to be used in Go tooling.

Let me know if you have additional thoughts or scenarios where this approach might fall short.

@iliakondratev
Copy link
Collaborator

Here's an example of how build flags help avoid similar package conflicts in GoLand (without a Bazel plugin): link

@H5-O5
Copy link
Contributor Author

H5-O5 commented Nov 21, 2024

OK. I got it. The filter should be looking at +build ignore instead of package name.

fyi, this is where the placeholder go file is created:

https://github.com/bazel-contrib/rules_go/blob/63b0dcb1ebf8678997fea7a6b253214aa4a9f447/go/tools/builders/protoc.go#L189

Could you consider this patch instead?

     return files.stream()
         .map(file -> VfsUtils.resolveVirtualFile(file, /* refreshIfNeeded= */ false))
         .filter(Objects::nonNull)
         .map(psiManager::findFile)
         .filter(GoFile.class::isInstance)
         .map(GoFile.class::cast)
+        .filter(goFile -> !Objects.equals(goFile.getBuildFlags(), "ignore"))
         .map(GoFile::getCanonicalPackageName) // strips _test suffix from test packages
         .filter(Objects::nonNull)
         .filter(packageName -> !packageName.equals("ignore"))

If so, I'd like to make a PR of it.

@iliakondratev
Copy link
Collaborator

Hi @H5-05, thanks for the patch—it looks good! Please go ahead and open a PR, we’ll review it.

H5-O5 added a commit to H5-O5/intellij that referenced this issue Nov 21, 2024
This fixed the indexing problem caused by retrieving the wrong package name.

fixes bazelbuild#7010
iliakondratev pushed a commit that referenced this issue Nov 27, 2024
This fixed the indexing problem caused by retrieving the wrong package name.

fixes #7010
@github-project-automation github-project-automation bot moved this from Untriaged to Done in Bazel IntelliJ Plugin Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-maintainer Awaiting review from Bazel team on issues lang: go Go rules integration product: GoLand GoLand plugin type: bug
Projects
Development

Successfully merging a pull request may close this issue.

4 participants