Open w65536 opened 2 years ago
Originally posted by @ieure in https://github.com/hooklift/gowsdl/issues/218#issuecomment-933800124
For #223, the issue is 100% gowsdl. It should probably put each ns' schema into its own subpackage based on its ns name, so you have
svcX.DuplicateComplexType
andsvc1.DuplicateComplexType
and the correct imports get added as needed.
I agree that this would be the correct approach if it can be made to work properly. There are a number reasons why I didn't try this yet:
dotnet-svcutil
for C# does not create C# namespaces for this case. I just resolves the naming collisions by adding numbers (1, 2, 3, ...) to those type names that would otherwise create collisions with existing names in other XML namespaces. It leaves the non-colliding type names alone at global scope.
This issue refers to one particular problem with namespaces, but I assume it should be looked at in a broader context of namespaces in general.
I start with describing the particular problem of name collisions and will address the more general topic at the end.
Scenario
This is a real scenario. Let's assume we have a service svcX with two additional services, svc1 and svc2, each in a separate namespace. All the three happen to use the same element names, "duplicateElement" and "duplicateComplexType", which is valid since they are in separate namespaces.
types.xsd (namespace for svcX http://www.example.com/svcX) imports the other two namespaces located in svc1.xsd (http://www.example.com/svc1) and svc2.xsd (http://www.example.com/svc2). (I omit representing the .wsdl file here since it does not add any value for understanding the problem.) These definitions result in the generated Go code in example.go at the end.
types.xsd:
svc1.xsd:
svc2.xsd:
Above definitions result in generated example.go:
Obviously this code does not compile due to redeclared types, i.e. naming collisions.
The scenario described here is "simple" in the sense that the types are only used within the same namespace. One could also envision such types being used from a different namespace, thus further complicating matters.
Solution Approaches
With respect to the scenario and problem described above, a few solution approaches come to mind. Approaches 1-3 attempt to change the names of duplicate types by e.g. adding some number or other namespace identifier to the name for differentiation. Approaches 1-2 have the undesired side effect that names of all types coming from different namespaces are modified (i.e. not just those colliding).
The difficult part when only working in the template, is to make sure that all occurrences of possible name collisions are caught and that they are caught for both the type definition and all locations where those types are used. https://github.com/hooklift/gowsdl/pull/218 proposes an approach that could help, although it "only" addresses attributes (which are a special case because they must have a namespace prefix according to specification) and it does not address name collisions.
Namespaces
I understand that part of this problem may be due to Go's limitations with XML namespace handling (the details of which I am not familiar with). The problem described above is just one particular problem with namespaces, resulting in naming collisions. But there are other problems and missing functionalities with namespaces too. I have also gone through existing issues and pull request that address similar or at least related problems:
Directly related to name collisions:
Other namespace related problems that should be considered for synergies for solution approach:
I do believe that namespace handling should be implemented in a consistent manner across all related functionalities of gowsdl. Whatever approach is chosen should make the resolution of other namespace related problems possible and easier.
Eager to hear what people think who are familiar with both Go's XML namespace support and gowsdl's implementation thus far.