Skip to content

Commit

Permalink
Merge pull request #333 from capnproto/enhancement/promised-cap
Browse files Browse the repository at this point in the history
Return capnp.Client from promised :Capability type
  • Loading branch information
lthibault authored Nov 14, 2022
2 parents 748d762 + 02b88e0 commit 394d2cf
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 573 deletions.
99 changes: 99 additions & 0 deletions capnpc-go/any_pointer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import "capnproto.org/go/capnp/v3/internal/schema"

type anyPointerRenderStrategy interface {
StructParams() any
ListParams() any
CapabilityParams() any
PtrParams() any
}

type anyPointer struct {
G *generator
Type schema.Type
}

func (ap anyPointer) Render(s anyPointerRenderStrategy) error {
switch ap.Type.AnyPointer().Which() {
case schema.Type_anyPointer_Which_unconstrained:
return ap.RenderUnconstrained(s)

case schema.Type_anyPointer_Which_parameter:
// TODO(soon): implement parameter
case schema.Type_anyPointer_Which_implicitMethodParameter:
// TODO(soon): implement implicit method parameter
}

return ap.G.r.Render(s.PtrParams())
}

func (ap anyPointer) RenderUnconstrained(s anyPointerRenderStrategy) error {
switch ap.Type.AnyPointer().Unconstrained().Which() {
case schema.Type_anyPointer_unconstrained_Which_struct:
return ap.G.r.Render(s.StructParams())

case schema.Type_anyPointer_unconstrained_Which_list:
return ap.G.r.Render(s.ListParams())

case schema.Type_anyPointer_unconstrained_Which_capability:
return ap.G.r.Render(s.CapabilityParams())
}

return ap.G.r.Render(s.PtrParams())
}

type structAnyPointerRenderStrategy struct {
Params structFieldParams
Default staticDataRef
}

func (s structAnyPointerRenderStrategy) StructParams() any {
return s.PtrParams() // TODO(soon): implement AnyStruct
}

func (s structAnyPointerRenderStrategy) ListParams() any {
return s.PtrParams() // TODO(soon): implement AnyList
}

func (s structAnyPointerRenderStrategy) CapabilityParams() any {
return structCapabilityFieldParams(s.Params)
}

func (s structAnyPointerRenderStrategy) PtrParams() any {
return structPointerFieldParams{
structFieldParams: s.Params,
Default: s.Default,
}
}

type promiseAnyPointerRenderStrategy struct {
G *generator
Node *node
Field field
}

func (s promiseAnyPointerRenderStrategy) StructParams() any {
return s.PtrParams() // TODO(soon): implement AnyStruct
}

func (s promiseAnyPointerRenderStrategy) ListParams() any {
return s.PtrParams() // TODO(soon): implement AnyList
}

func (s promiseAnyPointerRenderStrategy) CapabilityParams() any {
return promiseCapabilityFieldParams(s)
}

func (s promiseAnyPointerRenderStrategy) PtrParams() any {
return promiseFieldAnyPointerParams(s)
}

func isAnyCap(ap schema.Type_anyPointer) bool {
if ap.Which() != schema.Type_anyPointer_Which_unconstrained {
return false
}

which := ap.Unconstrained().Which()
return which == schema.Type_anyPointer_unconstrained_Which_capability
}
41 changes: 18 additions & 23 deletions capnpc-go/capnpc-go.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ func (g *generator) Value(rel *node, t schema.Type, v schema.Value) (string, err
}

// capability pointer?
if t.AnyPointer().Which() == schema.Type_anyPointer_Which_unconstrained &&
t.AnyPointer().Unconstrained().Which() == schema.Type_anyPointer_unconstrained_Which_capability {
if isAnyCap(t.AnyPointer()) {
return "nil", nil // static values of *Client are always nil.
}

Expand Down Expand Up @@ -590,29 +589,22 @@ func (g *generator) defineField(n *node, f field) (err error) {
})

case schema.Type_Which_anyPointer:
var defref staticDataRef
if p, err := def.AnyPointer(); err != nil {
p, err := def.AnyPointer()
if err != nil {
return err
} else if p.IsValid() {
defref, err = g.data.copyData(p)
if err != nil {
return err
}
}

// capability pointer?
if t.AnyPointer().Which() == schema.Type_anyPointer_Which_unconstrained &&
t.AnyPointer().Unconstrained().Which() == schema.Type_anyPointer_unconstrained_Which_capability {
return g.r.Render(structCapabilityFieldParams(params))
s := structAnyPointerRenderStrategy{Params: params}
if p.IsValid() {
if s.Default, err = g.data.copyData(p); err != nil {
return err
}
}

// TODO: handle other pointer types

// Fall back to default case => generic pointer value
return g.r.Render(structPointerFieldParams{
structFieldParams: params,
Default: defref,
})
return anyPointer{
G: g,
Type: t,
}.Render(s)

case schema.Type_Which_list:
var defref staticDataRef
Expand Down Expand Up @@ -754,8 +746,7 @@ func makeTypeRef(t schema.Type, rel *node, nodes nodeMap) (typeRef, error) {
}
case schema.Type_Which_anyPointer:
// capability pointer?
if t.AnyPointer().Which() == schema.Type_anyPointer_Which_unconstrained &&
t.AnyPointer().Unconstrained().Which() == schema.Type_anyPointer_unconstrained_Which_capability {
if isAnyCap(t.AnyPointer()) {
return typeRef{name: "Client", imp: capnpImportSpec}, nil
}

Expand Down Expand Up @@ -1055,11 +1046,15 @@ func (g *generator) definePromiseField(n *node, f field) error {
}
return g.r.Render(params)
case schema.Type_Which_anyPointer:
return g.r.Render(promiseFieldAnyPointerParams{
return anyPointer{
G: g,
Type: t,
}.Render(promiseAnyPointerRenderStrategy{
G: g,
Node: n,
Field: f,
})

case schema.Type_Which_interface:
ni, err := g.nodes.mustFind(t.Interface().TypeId())
if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion capnpc-go/templateparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,17 @@ type promiseFieldStructParams struct {
Default staticDataRef
}

type promiseFieldAnyPointerParams struct {
type promiseFieldParams struct {
G *generator
Node *node
Field field
}

type (
promiseFieldAnyPointerParams promiseFieldParams
promiseCapabilityFieldParams promiseFieldParams
)

type promiseFieldInterfaceParams struct {
G *generator
Node *node
Expand Down
3 changes: 3 additions & 0 deletions capnpc-go/templates/promiseCapabilityField
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
func (p {{.Node.Name}}_Future) {{.Field.Name|title}}() capnp.Client {
return p.Future.Field({{.Field.Slot.Offset}}, nil).Client()
}
4 changes: 2 additions & 2 deletions internal/aircraftlib/aircraft.capnp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions rpc/internal/testcapnp/test.capnp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 394d2cf

Please sign in to comment.