Skip to content

Commit

Permalink
THRIFT-4797: Go import improvements
Browse files Browse the repository at this point in the history
This change improves two problems in go code imports:

1. Always rename import the thrift package into "thrift", as we allow
   the user to use a different library to replace the official one from
   the compiler command line, this makes sure that in compiler generated
   go code we can always blindly use "thrift.*".

2. We added auto rename import dedup in d9019fc, but in that change
   for system packages we always use the full import path as the dedup
   identifier, so system package "database/sql/driver" would not be
   detected as a conflict against a thrift go namespace of
   "foo.bar.driver". Use the part after the last "/" in system packages
   as the dedup identifier instead.
  • Loading branch information
fishy committed Aug 1, 2021
1 parent c8ae621 commit 2c78047
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 9 deletions.
5 changes: 3 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

### Go

- [THRIFT-5369](https://issues.apache.org/jira/browse/THRIFT-5369) - TConfiguration.GetMaxMessageSize() now also applies to container sizes in TProtocol implementations provided
- [THRIFT-5404](https://issues.apache.org/jira/browse/THRIFT-5404) - TTransportException.Timeout would correctly return true when it's connect timeout during TSocket.Open call
- [THRIFT-5389](https://issues.apache.org/jira/browse/THRIFT-5389) - The compiler now generates correct go code with thrift constant defined on optional enum/typedef fields
- [THRIFT-4797](https://issues.apache.org/jira/browse/THRIFT-4797) - The compiler now correctly auto renames import thrift namespaces when they collide with system imports


## 0.14.2
Expand All @@ -23,7 +24,7 @@

### Go

- [THRIFT-5369](https://issues.apache.org/jira/browse/THRIFT-5369) - No longer pre-allocating the whole container (map/set/list) in compiled go code to avoid huge allocations on malformed messages
- [THRIFT-5369](https://issues.apache.org/jira/browse/THRIFT-5369) - TConfiguration.GetMaxMessageSize() now also applies to container sizes in TProtocol implementations provided


## 0.14.1
Expand Down
48 changes: 42 additions & 6 deletions compiler/cpp/src/thrift/generate/t_go_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -854,16 +854,50 @@ string t_go_generator::render_program_import(const t_program* program, string& u
return result;
}

/**
* Render import lines for the system packages.
*
* The arg system_packages supports the following two options for import auto
* rename in case duplications happens:
*
* 1. The full import path without double quotation marks, with part after the
* last "/" as the import identifier. e.g.:
* - "context" (context)
* - "database/sql/driver" (driver)
* 2. A rename import with double quotation marks around the full import path,
* with the part before the first space as the import identifier. e.g.:
* - "thrift \"github.com/apache/thrift/lib/go/thrift\"" (thrift)
*
* If a system package's package name is different from the last part of its
* full import path, please always rename import it for dedup to work correctly,
* e.g. "package \"github.com/org/go-package\"".
*
* @param system_packages
*/
string t_go_generator::render_system_packages(std::vector<string>& system_packages) {
string result = "";

for (vector<string>::iterator iter = system_packages.begin(); iter != system_packages.end(); ++iter) {
string package = *iter;
result += "\t\""+ package +"\"\n";
string identifier = package;
auto space_pos = package.find(" ");
if (space_pos != string::npos) {
// This is a rename import line, no need to wrap double quotation marks.
result += "\t"+ package +"\n";
// The part before the first space is the import identifier.
identifier = package.substr(0, space_pos);
} else {
result += "\t\""+ package +"\"\n";
// The part after the last / is the import identifier.
auto slash_pos = package.rfind("/");
if (slash_pos != string::npos) {
identifier = package.substr(slash_pos+1);
}
}

// Reserve these package names in case the collide with imported Thrift packages
package_identifiers_set_.insert(package);
package_identifiers_.emplace(package, package);
package_identifiers_set_.insert(identifier);
package_identifiers_.emplace(package, identifier);
}
return result;
}
Expand Down Expand Up @@ -929,8 +963,9 @@ string t_go_generator::go_imports_begin(bool consts) {
}
system_packages.push_back("fmt");
system_packages.push_back("time");
system_packages.push_back(gen_thrift_import_);
return "import(\n" + render_system_packages(system_packages);
// For the thrift import, always do rename import to make sure it's called thrift.
system_packages.push_back("thrift \"" + gen_thrift_import_ + "\"");
return "import (\n" + render_system_packages(system_packages);
}

/**
Expand Down Expand Up @@ -2341,12 +2376,13 @@ void t_go_generator::generate_service_remote(t_service* tservice) {
system_packages.push_back("os");
system_packages.push_back("strconv");
system_packages.push_back("strings");
// For the thrift import, always do rename import to make sure it's called thrift.
system_packages.push_back("thrift \"" + gen_thrift_import_ + "\"");

f_remote << go_autogen_comment();
f_remote << indent() << "package main" << endl << endl;
f_remote << indent() << "import (" << endl;
f_remote << render_system_packages(system_packages);
f_remote << indent() << "\t\"" + gen_thrift_import_ + "\"" << endl;
f_remote << indent() << render_included_programs(unused_protection);
f_remote << render_program_import(program_, unused_protection);
f_remote << indent() << ")" << endl;
Expand Down
23 changes: 23 additions & 0 deletions lib/go/test/ConflictNamespaceTestE.thrift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
namespace go conflicte.driver

struct ThingE {
1: bool value
}
23 changes: 23 additions & 0 deletions lib/go/test/ConflictNamespaceTestF.thrift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
namespace go conflictf.thrift

struct ThingF {
1: bool value
}
12 changes: 12 additions & 0 deletions lib/go/test/ConflictNamespaceTestSuperThing.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,26 @@
# specific language governing permissions and limitations
# under the License.
#
namespace go conflict.super

include "ConflictNamespaceTestA.thrift"
include "ConflictNamespaceTestB.thrift"
include "ConflictNamespaceTestC.thrift"
include "ConflictNamespaceTestD.thrift"
include "ConflictNamespaceTestE.thrift"
include "ConflictNamespaceTestF.thrift"

struct SuperThing {
1: ConflictNamespaceTestA.ThingA thing_a
2: ConflictNamespaceTestB.ThingB thing_b
3: ConflictNamespaceTestC.ThingC thing_c
4: ConflictNamespaceTestD.ThingD thing_d
5: ConflictNamespaceTestE.ThingE thing_e
6: ConflictNamespaceTestF.ThingF thing_f
}

// Define an enum to force the import of database/sql/driver
enum Enum {
One = 1
Two = 2
}
6 changes: 5 additions & 1 deletion lib/go/test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ gopath: $(THRIFT) $(THRIFTTEST) \
ConflictNamespaceTestB.thrift \
ConflictNamespaceTestC.thrift \
ConflictNamespaceTestD.thrift \
ConflictNamespaceTestE.thrift \
ConflictNamespaceTestF.thrift \
ConflictNamespaceTestSuperThing.thrift \
ConflictNamespaceServiceTest.thrift \
DuplicateImportsTest.thrift \
Expand Down Expand Up @@ -74,6 +76,8 @@ gopath: $(THRIFT) $(THRIFTTEST) \
$(THRIFT) $(THRIFTARGS) ConflictNamespaceTestB.thrift
$(THRIFT) $(THRIFTARGS) ConflictNamespaceTestC.thrift
$(THRIFT) $(THRIFTARGS) ConflictNamespaceTestD.thrift
$(THRIFT) $(THRIFTARGS) ConflictNamespaceTestE.thrift
$(THRIFT) $(THRIFTARGS) ConflictNamespaceTestF.thrift
$(THRIFT) $(THRIFTARGS) ConflictNamespaceTestSuperThing.thrift
$(THRIFT) $(THRIFTARGS) ConflictNamespaceServiceTest.thrift
$(THRIFT) $(THRIFTARGS) -r DuplicateImportsTest.thrift
Expand All @@ -97,7 +101,7 @@ check: gopath
./gopath/src/dontexportrwtest \
./gopath/src/ignoreinitialismstest \
./gopath/src/unionbinarytest \
./gopath/src/conflictnamespacetestsuperthing \
./gopath/src/conflict/super \
./gopath/src/conflict/context/conflict_service-remote \
./gopath/src/servicestest/container_test-remote \
./gopath/src/duplicateimportstest \
Expand Down
27 changes: 27 additions & 0 deletions lib/go/test/tests/conflict_namespace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package tests

import (
"github.com/apache/thrift/lib/go/test/gopath/src/conflict/super"
)

// We just want to make sure that the compiler generated package compiles.
var _ = super.GoUnusedProtection__

0 comments on commit 2c78047

Please sign in to comment.