Skip to content

Commit d82c1b6

Browse files
protoc-gen-ent: support entgql.Annotation
Added support for `entgql.Annotation` to the `protoc-gen-ent` plugin. It should now be possible to generate an Ent schema and its GraphQL configuration from a Protocol Buffer file. The `opts.proto` was updated adding `GQL` child MessageTypes to the existing MessageTypes (`Schema`, `Field`, `Edge`). The associated generated code (`opts.pb.go`) was regenerated using `protoc-gen-go`. The AST generation code in `schemaast/annotation.go` was updated to know about the `entgql` annotations. The new method attempts to generate code similar to that in the documentation. The main package was updated to map the configuration settings in the updated `opts.proto` to the corresponding annotations for the schema, fields, and edges.
1 parent bbd64e9 commit d82c1b6

File tree

4 files changed

+698
-85
lines changed

4 files changed

+698
-85
lines changed

entproto/cmd/protoc-gen-ent/main.go

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ package main
1717
import (
1818
"flag"
1919
"fmt"
20+
"strings"
2021

22+
"entgo.io/contrib/entgql"
2123
entopts "entgo.io/contrib/entproto/cmd/protoc-gen-ent/options/ent"
2224
"entgo.io/contrib/schemast"
2325
"entgo.io/ent"
26+
"entgo.io/ent/schema"
2427
"entgo.io/ent/schema/edge"
2528
"entgo.io/ent/schema/field"
2629
"google.golang.org/protobuf/compiler/protogen"
@@ -108,8 +111,37 @@ func toSchema(m *protogen.Message, opts *entopts.Schema) (*schemast.UpsertSchema
108111
if opts.Name != nil {
109112
name = opts.GetName()
110113
}
114+
var annotations []schema.Annotation
115+
gql := opts.GetGql()
116+
if gql != nil {
117+
if gql.GetQueryField() {
118+
if gql.GetQueryFieldName() != "" {
119+
annotations = append(annotations, entgql.QueryField(gql.GetQueryFieldName()).Annotation)
120+
} else {
121+
annotations = append(annotations, entgql.QueryField().Annotation)
122+
}
123+
}
124+
if gql.GetType() != "" {
125+
annotations = append(annotations, entgql.Type(gql.GetType()))
126+
}
127+
if gql.GetRelayConnection() {
128+
annotations = append(annotations, entgql.RelayConnection())
129+
}
130+
var create, update = gql.GetMutationCreate(), gql.GetMutationUpdate()
131+
if create || update {
132+
var options []entgql.MutationOption
133+
if create {
134+
options = append(options, entgql.MutationCreate())
135+
}
136+
if update {
137+
options = append(options, entgql.MutationUpdate())
138+
}
139+
annotations = append(annotations, entgql.Mutations(options...))
140+
}
141+
}
111142
out := &schemast.UpsertSchema{
112-
Name: name,
143+
Name: name,
144+
Annotations: annotations,
113145
}
114146
for _, f := range m.Fields {
115147
if isEdge(f) {
@@ -130,7 +162,16 @@ func toSchema(m *protogen.Message, opts *entopts.Schema) (*schemast.UpsertSchema
130162
}
131163

132164
func isEdge(f *protogen.Field) bool {
133-
return f.Desc.Kind() == protoreflect.MessageKind
165+
isMessageKind := f.Desc.Kind() == protoreflect.MessageKind
166+
if isMessageKind {
167+
switch f.Desc.Message().FullName() {
168+
case "google.protobuf.Timestamp":
169+
return false
170+
case "google.type.Date":
171+
return false
172+
}
173+
}
174+
return isMessageKind
134175
}
135176

136177
func toEdge(f *protogen.Field) (ent.Edge, error) {
@@ -194,6 +235,15 @@ func toField(f *protogen.Field) (ent.Field, error) {
194235
values = append(values, string(pbEnum.Get(i).Name()))
195236
}
196237
fld = field.Enum(name).Values(values...)
238+
case protoreflect.MessageKind:
239+
switch f.Desc.Message().FullName() {
240+
case "google.protobuf.Timestamp":
241+
fld = field.Time(name)
242+
case "google.type.Date":
243+
fld = field.Time(name)
244+
default:
245+
return nil, fmt.Errorf("protoc-gen-ent: unsupported kind %q", f.Desc.Kind())
246+
}
197247
default:
198248
return nil, fmt.Errorf("protoc-gen-ent: unsupported kind %q", f.Desc.Kind())
199249
}
@@ -214,6 +264,43 @@ func applyFieldOpts(fld ent.Field, opts *entopts.Field) {
214264
d.Tag = opts.GetStructTag()
215265
d.StorageKey = opts.GetStorageKey()
216266
d.SchemaType = opts.GetSchemaType()
267+
268+
gql := opts.GetGql()
269+
if gql != nil {
270+
var annotations []schema.Annotation
271+
if gql.GetOrderField() {
272+
if gql.GetOrderFieldName() != "" {
273+
annotations = append(annotations, entgql.OrderField(gql.GetOrderFieldName()))
274+
} else {
275+
annotations = append(annotations, entgql.OrderField(strings.ToUpper(fld.Descriptor().Name)))
276+
}
277+
}
278+
if gql.GetType() != "" {
279+
annotations = append(annotations, entgql.Type(gql.GetType()))
280+
}
281+
skipType, skipEnum, skipOrder, skipWhere, skipCreate, skipUpdate := gql.GetSkipType(), gql.GetSkipEnumField(), gql.GetSkipOrderField(), gql.GetSkipWhereInput(), gql.GetSkipMutationCreateInput(), gql.GetSkipMutationUpdateInput()
282+
if skipType || skipEnum || skipOrder || skipWhere || skipCreate || skipUpdate {
283+
var skipModeVals = []bool{
284+
skipType, skipEnum, skipOrder, skipWhere, skipCreate, skipUpdate,
285+
}
286+
var skipModeList = []entgql.SkipMode{
287+
entgql.SkipType,
288+
entgql.SkipEnumField,
289+
entgql.SkipOrderField,
290+
entgql.SkipWhereInput,
291+
entgql.SkipMutationCreateInput,
292+
entgql.SkipMutationUpdateInput,
293+
}
294+
var skipMode entgql.SkipMode
295+
for i, mode := range skipModeList {
296+
if skipModeVals[i] {
297+
skipMode |= mode
298+
}
299+
}
300+
annotations = append(annotations, entgql.Skip(skipMode))
301+
}
302+
d.Annotations = annotations
303+
}
217304
}
218305

219306
func applyEdgeOpts(edg ent.Edge, opts *entopts.Edge) {
@@ -229,6 +316,34 @@ func applyEdgeOpts(edg ent.Edge, opts *entopts.Edge) {
229316
Columns: sk.GetColumns(),
230317
}
231318
}
319+
320+
gql := opts.GetGql()
321+
if gql != nil {
322+
var annotations []schema.Annotation
323+
skipType, skipWhere, skipCreate, skipUpdate := gql.GetSkipType(), gql.GetSkipWhereInput(), gql.GetSkipMutationCreateInput(), gql.GetSkipMutationUpdateInput()
324+
if skipType || skipWhere || skipCreate || skipUpdate {
325+
var skipModeVals = []bool{
326+
skipType, skipWhere, skipCreate, skipUpdate,
327+
}
328+
var skipModeList = []entgql.SkipMode{
329+
entgql.SkipType,
330+
entgql.SkipWhereInput,
331+
entgql.SkipMutationCreateInput,
332+
entgql.SkipMutationUpdateInput,
333+
}
334+
var skipMode entgql.SkipMode
335+
for i, mode := range skipModeList {
336+
if skipModeVals[i] {
337+
skipMode |= mode
338+
}
339+
}
340+
annotations = append(annotations, entgql.Skip(skipMode))
341+
}
342+
if gql.GetRelayConnection() {
343+
annotations = append(annotations, entgql.RelayConnection())
344+
}
345+
d.Annotations = annotations
346+
}
232347
}
233348

234349
type placeholder struct {

0 commit comments

Comments
 (0)