-
Notifications
You must be signed in to change notification settings - Fork 8
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
feat: schema changes to support SumType #1322
Conversation
backend/schema/sumtype.go
Outdated
Pos: posToProto(s.Pos), | ||
Comments: s.Comments, | ||
Name: s.Name, | ||
Variants: variants, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have a helper for this, so you don't have to construct your own list!
Variants: variants, | |
Variants: nodeListToProto[*schemapb.Type](s.Variants), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, actually:
Variants: variants, | |
Variants: slices.Map(s.Variants, typeToProto), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done :D
backend/schema/jsonschema.go
Outdated
for i, v := range node.Variants { | ||
variants[i] = jsonschema.SchemaOrBool{TypeObject: nodeToJSSchema(v, refs)} | ||
} | ||
return &jsonschema.Schema{OneOf: variants} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Though, this should be using {"kind": xyz, "value": ...}
, or is that in a followup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi - from feedback during the design sync we actually lifted the original struct out of value
, so it'll just be an additional field named @_kind
(prefixed with @_
to avoid conflicts) at the top level now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm, @_kind
can still conflict though if the sum type variant is a map:
sumtype SumType = {String: String} | Int
var value SumType = {"@_kind": "foo"}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah good point, i misunderstood your prior comment from the design sync. we can go with the kind/value approach then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
backend/schema/parser.go
Outdated
@@ -41,6 +41,7 @@ var ( | |||
{Name: "String", Pattern: `"(?:\\.|[^"])*"`}, | |||
{Name: "Number", Pattern: `[0-9]+(?:\.[0-9]+)?`}, | |||
{Name: "Punct", Pattern: `[%/\-\_:[\]{}<>()*+?.,\\^$|#~!\'@]`}, | |||
{Name: "Equals", Pattern: `=`}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just add this to Punct
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
backend/schema/sumtype.go
Outdated
Pos Position `parser:"" protobuf:"1,optional"` | ||
|
||
Comments []string `parser:"@Comment*" protobuf:"2"` | ||
Name string `parser:"'sumtype' @Ident Equals" protobuf:"3"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be just '='
by adding =
to Punct
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oo lala, thank you!
"type": "string" | ||
} | ||
}, | ||
"type": "integer" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is valid is it? Unless I'm misunderstand this schema a type of "integer" can't have properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
approved (pending a decision on where we land on the wrapped + kind
vs embeded + @_kind
thing)
I think there's a JSON schema validation round trip test that we should use here to verify it's working as intended. |
Hey folks! Posting a summary here to round this out:
|
I don't see a test here exercising this... ie. there's no input value anywhere (I can see?) with |
@@ -307,7 +332,8 @@ func TestInvalidEnumValidation(t *testing.T) { | |||
"any": [{"name": "Name"}, "string", 1, 1.23, true, "2018-11-13T20:20:39+00:00", ["one"], {"one": 2}, null], | |||
"keyValue": {"key": "string", "value": 1}, | |||
"stringEnumRef": "B", | |||
"intEnumRef": 3 | |||
"intEnumRef": 3, | |||
"sumTypeRef": 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where's the @_kind
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add that to TestInvalidEnumValidation too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I see it in the schema, but it's not used in the value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two cases where I don't think this will approach will work:
- How do we differentiate between a sum type with Float and Int without a kind?
- How does
@_kind
work if the type being discriminated is a map that can contain@_kind
as a key.?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhhhh ok this finally make sense to me now. I'll think about this a bit more and try out whatever I come up with with the rest of the types to make sure we can discriminate.
btw, as far as I'm aware we won't need to worry about the issue of representing the |
Agreed @worstell, but maybe let's have a quick chat about it in the daily sync? The Maybe we support bare sum types if there's no ambiguity, and the |
@alecthomas sounds good, let's chat in sync! making sum types enums could be another solution here, though it introduces a bunch of other complexity (worth it if we determine this to be the right approach conceptually, though). If we structured them as enums, each variant would have a name, a type, and possibly a "raw value" (inspired by your Swift reference). the value of in Go, all variants are necessarily either type aliases or themselves structs. the alias or struct name will become the variant name. in other runtimes we can structure the approach to ensure we have some way of deriving variant "names". ex:
|
Reverts everything in #1322 except for the addition of `=` to `Punct` in `backend/schema/parser.go`, which we will still be using for value enums. Going forward, sumtypes will be implemented as type enums.
Design doc: https://hackmd.io/TZqMfuyHTYaXd1gSECbpFg?view