Skip to content

THRIFT-6200: Use the declaring package for arguments in the Go -remote stub - #3817

Open
slachiewicz wants to merge 1 commit into
apache:masterfrom
slachiewicz:THRIFT-6200
Open

slachiewicz wants to merge 1 commit into
apache:masterfrom
slachiewicz:THRIFT-6200

Conversation

@slachiewicz

@slachiewicz slachiewicz commented Sep 8, 2026

Copy link
Copy Markdown
Member

A service method that takes an enum declared in an included file generates a -remote stub that does not compile. The stub qualifies the enum with the service's own package:

argvalue1 := includestest.Numberz(tmp1)

Numberz is declared in ThriftTest.thrift and generated into thrifttest, which the stub already imports.

gopath/src/includestest/test_service-remote/test_service-remote.go:179:29: undefined: includestest.Numberz
gopath/src/includestest/extended_service-remote/extended_service-remote.go:197:29: undefined: includestest.Numberz

The container/exception branch has the same defect one step removed. It reads the argument through the function's args struct, and when the function is inherited from a service declared in an included file the constructor is qualified with the wrong package as well:

extended2_service-remote.go:185:36: undefined: includestest.NewNamespacedServiceTakeListArgs

func_to_service recorded only the declaring service's name. It now records the service itself, the enum and container branches resolve the package with module_name() the way the struct branch already did, and the stub imports the package of every ancestor service, so a function inherited across two include levels resolves too.

lib/go/test builds includestest but none of its -remote packages, which is why this never showed up. NamespacedService gains list, map and exception arguments and extends a service in a new NamespacedBaseTest.thrift, so Extended2Service inherits functions from one and two include levels away. Its three -remote packages are added to the check list.

Regenerating every IDL under test/, lib/go/test/ and tutorial/ with master's generator and with this one touches 5 of 332 generated files, all -remote stubs of the two test IDLs: the Numberz line in test_service-remote and extended_service-remote, the baseList constructor in namespaced_service-remote, and in extended2_service-remote the four constructors plus the import of the grandparent package.

Still out of scope, and shared with the enum and struct branches: a type declared in a file the program reaches only transitively, used as an argument by an inherited function, still resolves to a package the stub does not import.

Independent of #3812; different code path, no shared lines.

This change was created with AI assistance.

@Jens-G

Jens-G commented Sep 11, 2026

Copy link
Copy Markdown
Member

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

One related case that fits THRIFT-6200 but is not covered by this change: the container/exception branch of generate_service_remote still qualifies the args constructor with package_name_aliased. Since THRIFT-5002, func_to_service records which service declares an inherited function, but only its name, not its package. If that service comes from an included file, the stub does not compile:

// ParentA.thrift
namespace go parenta
service ParentService {
  void takeList(1: list<i32> xs),
}

// ChildB.thrift
include "ParentA.thrift"
namespace go childb
service ChildService extends ParentA.ParentService {
}
child_service-remote.go:163:30: undefined: childb.NewParentServiceTakeListArgs

That is with the compiler built from this branch. map, list<struct> and exception arguments fail the same way, while enum and struct arguments inherited this way do compile. The services in IncludesTest.thrift do not reach this branch, because the functions they inherit from other files take no container arguments. Qualifying containerStruct with the package of the declaring service would fix it.

<< '\n';
f_remote << indent() << "containerStruct" << i << " := " << package_name_aliased << ".New"
<< argumentsName << "()" << '\n';
f_remote << indent() << err2 << " := containerStruct" << i << ".ReadField" << (i + 1) << "(context.Background(), "

🤖 Generated with Claude Code

@slachiewicz slachiewicz changed the title THRIFT-6200: Use the declaring package for enum arguments in the Go -remote stub THRIFT-6200: Use the declaring package for arguments in the Go -remote stub Sep 13, 2026
@slachiewicz

Copy link
Copy Markdown
Member Author

Folded into the amended commit. func_to_service now keeps the t_service* and the container/exception branch qualifies the args constructor with module_name() of that service, the same way the struct and enum branches do. The stub also imports the package of every ancestor service, since a function inherited from a service two include levels away resolved to the local package for the same reason.

NamespacedService in lib/go/test gains list, map and exception arguments and extends a service in a new NamespacedBaseTest.thrift, so Extended2Service inherits across one and two include levels. extended2_service-remote joins the check list. Your ParentA/ChildB example builds with this branch.

This comment was created with AI assistance.

…e stub

Client: go

The stub qualified two things with the package it was generated into even
when they live in an included file, and the stub then did not compile:

- an enum argument, written as package_name_aliased unconditionally while
  the struct branch a few lines below already resolves the package with
  module_name();
- the args struct of a container or exception argument on a function
  inherited from a service declared in an included file. func_to_service
  recorded only the declaring service's name, so its package was lost.

func_to_service now records the service itself, the enum and container
branches resolve the package the same way the struct branch does, and the
stub imports the package of every ancestor service, so a function inherited
across more than one include level resolves too.

lib/go/test built includestest but none of its -remote packages, which is
why this stayed green. NamespacedService gains list, map and exception
arguments and now extends a service in a new NamespacedBaseTest.thrift,
so Extended2Service inherits functions from one and two include levels
away; its three -remote packages join the check list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build and general CI cmake, automake and build system changes compiler golang Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants