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

generate and compile Go from Protobuf #14714

Merged
merged 7 commits into from
Mar 14, 2022

Conversation

tdyas
Copy link
Contributor

@tdyas tdyas commented Mar 7, 2022

Complete Go protobuf support by actually wiring up compilation of the generated Go sources.

Closes #12820.

[ci skip-rust]

[ci skip-build-wheels]

@tdyas
Copy link
Contributor Author

tdyas commented Mar 7, 2022

Open questions:

1. Dependencies between protobuf files are not handled by the PR yet. This should probably walk the dependencies of the protobuf_source target and then use BuildGoPackageTargetRequest to obtain the applicable BuildGoPackageRequest. Protobuf dependency inference will automatically add those dependencies.
2. This does not yet handle merging the compilation of multiple proto files with the same import path. We should probably look for sibling proto files with the same import path (from go_package) and merge their builds into one build.
3. Bug in GoCodegenBuildRequest rules?: Using a protobuf_sources as the dependency for a go_package target is not being expanded to the underlying protobuf_source targets. Target generation has actually run since I could use the file-level target instead in the test.
4. The current method of using ImportPathToPackages to resolve import paths to package addresses won't work with multiple go.mod's. There will eventually need to be a way for to know what go.mod is in effect for this target in order to know where to scan for third-party packages for dependencies.

@tdyas
Copy link
Contributor Author

tdyas commented Mar 7, 2022

cc @Eric-Arellano

@tdyas tdyas mentioned this pull request Mar 7, 2022
@Eric-Arellano
Copy link
Contributor

  1. Bug in GoCodegenBuildRequest rules?

Yep. Fixed. Thanks for the report 🙌

  1. There will eventually need to be a way for to know what go.mod is in effect for this target in order to know where to scan for third-party packages for dependencies.

Yes. This will look like #14693, but Golang-ier. protobuf_source targets will declare which go.mod they belong to via a new plugin field. You use parametrize if you want it to work with multiple go.mods.

We still need to figure out how you refer to that go.mod, if you have a logical "name" like Python and JVM vs the path to it vs something else: #13114

  1. Dependencies between protobuf files are not handled by the PR yet. This should probably walk the dependencies of the protobuf_source target and then use BuildGoPackageTargetRequest to obtain the applicable BuildGoPackageRequest. Protobuf dependency inference will automatically add those dependencies.

I think so, and indeed Pants dep inference already handles inter-Protobuf dependencies.

But I also think this highly relates to your question 2. It seems possible that inter-Protobuf dependencies might end up belonging to the same package? If so, they need to be built together — not via a direct dependency.

  1. We should probably look for sibling proto files with the same import path (from `go_package) and merge their builds into one build.

We should, but also I think "sibling" isn't relevant here, right? It is possible for a protobuf_source file implemented in dir1/ to set the same import path as dir2/, even though not siblings.

I think we will need to create a module mapping of each import path to set of Protobuf files. That set needs to behave as an atomic unit.

It's convenient that this module mapping is the same way we will implement dependency inference from Go -> Protobuf! If Go imports a generated package, we must infer a dep on all protobuf_source targets that are part of the package: the whole set.


Question @tdyas, do we expect that users will need to set the go_package in their .proto file for the package? https://developers.google.com/protocol-buffers/docs/reference/go-generated mentions how you can set the value via CLI, and explicitly calls out Bazel using this. Got me wondering if this should be exposed as a field in the BUILD file?

Generally, it's valuable for Pants to try to stay closer to the standard way of doing things: that you can still use normal Protoc if you want. This is important for incremental adoption. Which would suggest it's better for people to set the option in their .proto file rather than relying on Pants magically setting up argv the right way.

We could also start with requiring you to add it, and if users find that too restrictive we can consider loosening this. Easier to make less strict than vice versa.

@tdyas
Copy link
Contributor Author

tdyas commented Mar 9, 2022

We still need to figure out how you refer to that go.mod, if you have a logical "name" like Python and JVM vs the path to it vs something else: #13114

Via the import path for the module?

@Eric-Arellano
Copy link
Contributor

Via the import path for the module?

Possibly! That would not fit well with the generic generate-lockfiles and resolves, but we already expect Go to be different than the other languages because Go has such an opinion already on the topic.

(It's probably better to discuss multiple go.mod at #13114. It shouldn't block this PR, so long as #14693 is viable.)

Tom Dyas added 5 commits March 11, 2022 00:22
[ci skip-rust]

[ci skip-build-wheels]
[ci skip-rust]

[ci skip-build-wheels]
[ci skip-rust]

[ci skip-build-wheels]
[ci skip-rust]

[ci skip-build-wheels]
[ci skip-rust]

[ci skip-build-wheels]
Tom Dyas added 2 commits March 11, 2022 10:37
[ci skip-rust]

[ci skip-build-wheels]
[ci skip-rust]

[ci skip-build-wheels]
@tdyas tdyas changed the title [WIIP] go: compile generated protoc output generate and compile Go from Protobuf Mar 11, 2022
@tdyas tdyas marked this pull request as ready for review March 11, 2022 17:30
@tdyas
Copy link
Contributor Author

tdyas commented Mar 11, 2022

This is ready for review.

The rules infer dependencies from generated Go code to existing Go packages (including the protobuf runtime) and dependencies on other Go Protobuf packages.

@tdyas tdyas requested a review from stuhood March 11, 2022 17:31
@tdyas
Copy link
Contributor Author

tdyas commented Mar 11, 2022

cc @chrisjrn in case there anything relevant here for JVM rules

@tdyas
Copy link
Contributor Author

tdyas commented Mar 14, 2022

ping

Copy link
Member

@stuhood stuhood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Eric-Arellano should probably still review, but here's my stamp.

@rule
async def setup_build_go_package_request_for_protobuf(
_: GoCodegenBuildProtobufRequest,
request: GoCodegenBuildProtobufRequest,
Copy link
Member

@stuhood stuhood Mar 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Eric-Arellano: Relative to #14751, I'm still not quite sure why Go needs a union separate from the GenerateSourcesRequest union, which already indicates that code can be generated for Go.

A lot of work went in here, and I won't block. But it would be good to be sure that it is necessary relative to using an existing BuildGoPackageRequest with a target which "can be converted to" Go, rather than one that already has matching field(sets) (i.e.: this code becoming codegen aware rather than using direct field access).

The inference @rules (on the other hand) do seem necessarily custom, since they map from protobuf sources to a Go path.

package_mapping: ImportPathToPackages,
go_protobuf_mapping: GoProtobufImportPathMapping,
analyzer: PackageAnalyzerSetup,
) -> BuildGoPackageRequest:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return a FallibleBuildGoPackageRequest to fail slow here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I realized this was a bad call on my part when adding the plugin API - we want ./pants check :: to fail gracefully. I think it's fine to fix this is a followup, given that it's changing the generic plugin hook

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do in follow-up.

@tdyas tdyas merged commit d2881ba into pantsbuild:main Mar 14, 2022
@tdyas tdyas deleted the golang_finish_protobuf branch March 14, 2022 22:08
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

Successfully merging this pull request may close these issues.

Go: support Protobuf
3 participants