Open bterlson opened 1 year ago
I'm currently working on a postgres emitter and this is how my current code handles these issues:
Namespaces get converted to schema. With nested namespaces being called there entire path with "_" between them.
namespace one.two.three
becomes
CREATE SCHEMA one_two_three
Models an Enum which get emitted are then part of the schema that was their namespace.
Regarding which namespaces to emit I currently have two modes my emitter can work in:
Regarding name collisions I already implemented logic that detects naming collisions. I had to implement that as the @entity(name) decorator can take a name parameter for naming the entity differently in the DB-representation. If there are collisions between names set in the decorator parameter and any other names (except anonymous names) my code throws an error. For the Edge-Case of a model-name colliding with a schema-name it just throws a warning. For anonymous names colliding with "regular" names, I only throw a warning.
An example of anonymous names are string union types. I convert them into enums and have to come up with some name for them. That name can then collide with a name that is in the actual TypeSpec-File. These collisions get handled with a counter in the output and only throw a warning.
For my emitter the naming problematic should already be taken care of, but it was not that trivial to implement. I can imagine that multiple domains/emitters will have to create names for things that are anonymous in TypeSpec as this is also the case with code-generation from openAPI-files and as TypeSpec is kind of similar to TypeScript which also allows more anonymous types than a lot of other languages IMO.
In TypeSpec, it is fairly easy to create multiple declarations with the same name, they just need to be in different namespaces. At the same time, emitted code generally does not want to include the TypeSpec namespace in its declaration names, either because this is not possible or just undesirable due to the added verbosity/confusion). So emitters need to handle this case gracefully, for example as the OA3 emitter does by prepending the namespace when needed.
Unfortunately the solution to this problem is not particularly straight forward, with a number of approaches available, and all having nasty tradeoffs:
The OpenAPI emitter takes a combination of approaches 1 and 4.
In any case we shouldn't require all emitter authors to muddle through this and provide some sort of solution in either the compiler or the framework (or recommend approach #4 if that's what we like).