-
Notifications
You must be signed in to change notification settings - Fork 16
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
Anonymous types must have locally-defined names in order to be stable #103
Comments
As per an offline discussion, all the inline type definitions must have a name defined for the initial implementation. This simplifies later adding support to infer names based on above suggested option 2(e.g. field names). |
There can be few alternatives to Option 1: Use an Ion structWe can use an Ion struct here which can hold more information about the name of inline type, like different names in different programming languages, a namespace to consider for when there is a collision of same inline names possible etc.
Option 2: Use annotationsWe can use annotations for a compact syntax then the struct in Option 1.
If we do decide to stick with
cc: @zslayton |
I did some thinking about this a while ago, here is what I had come up with... In theory, all code gen properties are one of (click on them for examples): Language-agnostic fields that just accept the data as the field value without any language specific cases
Language-specific fields that accept a struct with language-value pairs
Language-optional fields that can go either way and accept a language agnostic value and/or language-value pairs.
It’s a backwards compatible change for a codegen config property to go from language-agnostic to language-optional or to go from language-specific to language-optional, but it’s breaking to change a field from language-optional to anything else. Therefore, we should try to make fields language-agnostic or language-specific until we have a compelling case to make it language-optional. This pattern is especially useful because it's easy for a codegen tool to find the right values. First, find the Whatever we do, the configuration hierarchy should be We could choose from many different ways to structure the keys. One alternative to the above proposal is a flatter set of keys, like this:
^^ That was from some of my notes from nearly 18 months ago. I don't think there's too much difference between different structures, but I would suggest that we don't rely on constructing field names to form something like I would also suggest that we don't use a list of annotated values. I'd rather we be opinionated about a structure for the property values and force values that are similar in some way to be grouped together. I also think that the double annotations are going to be unwieldy to work with and unintuitive for users. Single annotations could be okay. (Click to expand examples)I don't love it, but I'm also not opposed to something like either of these:
|
Thanks for the detailed explanation Matthew! I think from your examples, language-specific sounds like the best solution to start with and infact having that specific syntax rather then the flatten one will make it much easier for user to specify everything in one place/one struct, rather then having different properties(e.g.
|
Suppose I have the following schema:
As it is currently implemented, the code generator might generate something like this. (I'm using Kotlin, rather than Java, for conciseness here, but the principle will still apply.)
Now, suppose I add a new field to
Foo
, like this:The code generator has no way of knowing how to keep the generated code stable, and would likely end up generating these classes:
In this scenario,
AnonymousType2
andBar
have been redefined in a way that will break the code of anyone who is using either one of these classes in any non-trivial way. This cannot be solved by sorting the anonymous types because the only sort attribute that would not result in types being moved/redefined would be the timestamp that the inline type was added to the schema for the first time.There are a few things that I think we must do in order to fix this problem, but I'm certainly open to hearing other solutions.
org.example.AnonymousType1
would instead beorg.example.Foo.AnonymousType1
. In Rust, it's a little trickier because you could end up with naming clashes where you create a module calledfoo
to hold children ofFoo
when there's already another module you're generating calledfoo
, but this is solvable.$code_gen_name
field, should use that name; otherwise...fields
constraint should be named after their respective fields. I.e.AnonymousType1
would be namedFoo.A
in Java/Kotlin.element
constraint should be namedElement
. I.e.AnonymousType2
would be namedBar.Element
in Java/Kotlin.type
orall_of
should have their constraints flattened into the containing type.one_of
constraint have two possible solutionsVariant0
..VariantN
, and everyone_of
constraint must have its own distinct counter (i.e. not a globally incremented counter). E.g.Car.Variant0
,Car.Variant1
, etc.ordered_elements
should be namedElement0
..ElementN
, and everyordered_elements
constraint must have its own distinct counter.I might be missing a case somewhere, but I think that mostly covers them all.
The text was updated successfully, but these errors were encountered: