Skip to content
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

chore(go): support get/set kernel API in go runtime #2178

Merged
merged 5 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 46 additions & 35 deletions packages/@jsii/go-runtime/jsii-experimental/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,54 +121,55 @@ type createResponse struct {
type DelRequest struct {
kernelRequester

Api string `json:"api"`
// Objref ObjRef
Api string `json:"api"`
Objref objref `json:"objref"`
}

type DelResponse struct {
kernelResponder
}

type GetRequest struct {
type getRequest struct {
kernelRequester

Api string `json:"api"`
Property *string `json:"property"`
// Objref ObjRef
Api string `json:"api"`
Property string `json:"property"`
Objref objref `json:"objref"`
}

type StaticGetRequest struct {
type staticGetRequest struct {
kernelRequester

Api string `json:"api"`
Fqn *FQN `json:"fqn"`
Property *string `json:"property"`
Api string `json:"api"`
Fqn FQN `json:"fqn"`
Property string `json:"property"`
}
type GetResponse struct {

type getResponse struct {
kernelResponder

Value Any `json:"value"`
Value interface{} `json:"value"`
}

type StaticSetRequest struct {
type setRequest struct {
kernelRequester

Api string `json:"api"`
Fqn *FQN `json:"fqn"`
Property *string `json:"property"`
Value Any `json:"value"`
Api string `json:"api"`
Property string `json:"property"`
Value interface{} `json:"value"`
Objref objref `json:"objref"`
}

type SetRequest struct {
type staticSetRequest struct {
kernelRequester

Api string `json:"api"`
Property *string `json:"property"`
Value Any `json:"value"`
// Objref ObjRef
Api string `json:"api"`
Fqn FQN `json:"fqn"`
Property string `json:"property"`
Value interface{} `json:"value"`
}

type SetResponse struct {
type setResponse struct {
kernelResponder
}

Expand Down Expand Up @@ -199,10 +200,10 @@ type invokeResponse struct {
type BeginRequest struct {
kernelRequester

Api string `json:"api"`
Method *string `json:"method"`
Args []Any `json:"args"`
// Objref ObjRef
Api string `json:"api"`
Method *string `json:"method"`
Args []interface{} `json:"args"`
Objref objref `json:"objref"`
}

type BeginResponse struct {
Expand All @@ -221,7 +222,7 @@ type EndRequest struct {
type EndResponse struct {
kernelResponder

Result Any `json:"result"`
Result interface{} `json:"result"`
}

type CallbacksRequest struct {
Expand All @@ -239,10 +240,10 @@ type CallbacksResponse struct {
type CompleteRequest struct {
kernelRequester

Api string `json:"api"`
Cbid *string `json:"cbid"`
Err *string `json:"err"`
Result Any `json:"result"`
Api string `json:"api"`
Cbid *string `json:"cbid"`
Err *string `json:"err"`
Result interface{} `json:"result"`
}

type CompleteResponse struct {
Expand Down Expand Up @@ -288,12 +289,12 @@ type Callback struct {
Cbid *string `json:"cbid"`
Cookie *string `json:"cookie"`
Invoke invokeRequest `json:"invoke"`
Get GetRequest `json:"get"`
Set SetRequest `json:"set"`
Get getRequest `json:"get"`
Set setRequest `json:"set"`
}

type OkayResponse struct {
Ok Any `json:"ok"`
Ok interface{} `json:"ok"`
}

type ErrorResponse struct {
Expand All @@ -318,6 +319,16 @@ func (r *invokeResponse) UnmarshalJSON(data []byte) error {
return unmarshalKernelResponse(data, (*response)(r))
}

func (r *getResponse) UnmarshalJSON(data []byte) error {
type response getResponse
return unmarshalKernelResponse(data, (*response)(r))
}

func (r *setResponse) UnmarshalJSON(data []byte) error {
type response setResponse
return unmarshalKernelResponse(data, (*response)(r))
}

// Custom unmarshaling for kernel responses, checks for presence of `error` key on json and returns if present
func unmarshalKernelResponse(data []byte, resstruct interface{}) error {
datacopy := make([]byte, len(data))
Expand Down
71 changes: 45 additions & 26 deletions packages/@jsii/go-runtime/jsii-experimental/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,31 @@ var (
clientOnce sync.Once
)

type Any interface{}

// The client struct owns the jsii child process and its io interfaces. It also
// owns a map (objects) that tracks all object references by ID. This is used
// to call methods and access properties on objects passed by the runtime
// process by reference.
type client struct {
process *exec.Cmd
RuntimeVersion string
writer *json.Encoder
reader *json.Decoder

// Keeping track of state that'll need cleaning up in close()
stdin io.WriteCloser
tmpdir string

objects map[interface{}]string
}

func CheckFatalError(e error) {
if e != nil {
log.Fatal(e)
}
}

// getClient returns a singleton client instance, initializing one the first
// time it is called.
func getClient() *client {
Expand Down Expand Up @@ -61,36 +86,10 @@ func closeClient() {
}
}

type Any interface{}

// The client struct owns the jsii child process and its io interfaces. It
// also owns a map that tracks all object references by ID. This is used to
// call methods and access properties on objects passed by the runtime process
// by reference.
type client struct {
process *exec.Cmd
RuntimeVersion string
writer *json.Encoder
reader *json.Decoder

// Keeping track of state that'll need cleaning up in close()
stdin io.WriteCloser
tmpdir string
// objects map[string]interface{}
objects map[interface{}]string
}

func CheckFatalError(e error) {
if e != nil {
log.Fatal(e)
}
}

// newClient starts the kernel child process and verifies the "hello" message
// was correct.
func newClient() (*client, error) {
// Initialize map of object instances
// objmap := make(map[string]interface{})
objmap := make(map[interface{}]string)

clientinstance := &client{
Expand Down Expand Up @@ -226,6 +225,26 @@ func (c *client) sinvoke(request staticInvokeRequest) (invokeResponse, error) {
return response, c.request(request, &response)
}

func (c *client) get(request getRequest) (getResponse, error) {
response := getResponse{}
return response, c.request(request, &response)
}

func (c *client) sget(request staticGetRequest) (getResponse, error) {
response := getResponse{}
return response, c.request(request, &response)
}

func (c *client) set(request setRequest) (setResponse, error) {
response := setResponse{}
return response, c.request(request, &response)
}

func (c *client) sset(request staticSetRequest) (setResponse, error) {
response := setResponse{}
return response, c.request(request, &response)
}

func (c *client) close() {
if c.process != nil {
c.stdin.Close()
Expand Down
73 changes: 73 additions & 0 deletions packages/@jsii/go-runtime/jsii-experimental/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,79 @@ func InvokeStatic(fqn FQN, method string, args []interface{}, returns interface{
}
}

func Get(property string, obj interface{}) {
client := getClient()

// Find reference to class instance in client
refid, found := client.findObjectRef(obj)

if !found {
panic("No Object Found")
}

_, err := client.get(getRequest{
Api: "get",
Property: property,
Objref: objref{JsiiInstanceId: refid},
})

if err != nil {
panic(err)
}

// Do we need to return Value from getResponse?
}

func StaticGet(fqn FQN, property string) {
client := getClient()

_, err := client.sget(staticGetRequest{
Api: "sget",
Fqn: fqn,
Property: property,
})

if err != nil {
panic(err)
}
}

func Set(property string, value, obj interface{}) {
client := getClient()

// Find reference to class instance in client
refid, found := client.findObjectRef(obj)

if !found {
panic("No Object Found")
}

_, err := client.set(setRequest{
Api: "set",
Property: property,
Objref: objref{JsiiInstanceId: refid},
})

if err != nil {
panic(err)
}
}

func StaticSet(fqn FQN, property string, value interface{}) {
client := getClient()

_, err := client.sset(staticSetRequest{
Api: "sset",
Fqn: fqn,
Property: property,
Value: value,
})

if err != nil {
panic(err)
}
}

// Close finalizes the runtime process, signalling the end of the execution to
// the jsii kernel process, and waiting for graceful termination. The best
// practice is to defer call thins at the beginning of the "main" function.
Expand Down
12 changes: 12 additions & 0 deletions packages/jsii-pacmak/lib/targets/go/runtime/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ export const JSII_INVOKE_FUNC = `${JSII_RT_ALIAS}.Invoke`;
// JSII static invoke
export const JSII_SINVOKE_FUNC = `${JSII_RT_ALIAS}.InvokeStatic`;

// JSII get request
export const JSII_GET_FUNC = `${JSII_RT_ALIAS}.Get`;

// JSII static get request
export const JSII_SGET_FUNC = `${JSII_RT_ALIAS}.StaticGet`;

// JSII set request
export const JSII_SET_FUNC = `${JSII_RT_ALIAS}.Get`;

// JSII static set request
export const JSII_SSET_FUNC = `${JSII_RT_ALIAS}.StaticSet`;

// MISC types & functions
// Jsii override struct type
export const JSII_OVERRIDE = `${JSII_RT_ALIAS}.Override`;
Expand Down
30 changes: 18 additions & 12 deletions packages/jsii-pacmak/lib/targets/go/runtime/method-call.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { CodeMaker } from 'codemaker';

import { GoProperty, ClassMethod, Struct } from '../types';
import { JSII_INVOKE_FUNC, JSII_SINVOKE_FUNC } from './constants';
import {
JSII_SGET_FUNC,
JSII_SSET_FUNC,
JSII_INVOKE_FUNC,
JSII_SINVOKE_FUNC,
} from './constants';
import { emitInitialization } from './util';

// NOOP type returns
Expand Down Expand Up @@ -88,15 +93,15 @@ export class StaticGetProperty {
public emit(code: CodeMaker) {
emitInitialization(code);

code.openBlock(`_jsii_.NoOpRequest(_jsii_.NoOpApiRequest`);
code.line(`Class: "${this.parent.parent.name}",`);
code.line(`Method: "${this.parent.property.name}",`);
code.close(`})`);
code.open(`${JSII_SGET_FUNC}(`);
code.line(`"${this.parent.parent.fqn}",`);
code.line(`"${this.parent.property.name}",`);
code.close(`)`);

const ret = this.parent.reference;
if (ret?.type?.type.isClassType() || ret?.type instanceof Struct) {
const ret = this.parent.property;
if (ret?.type?.type?.isClassType() || ret?.type instanceof Struct) {
code.line(`return ${this.parent.returnType}{}`);
} else if (ret?.type?.type.isEnumType()) {
} else if (ret?.type?.type?.isEnumType()) {
code.line(`return "ENUM_DUMMY"`);
} else {
code.line(`return ${this.getDummyReturn(this.parent.returnType)}`);
Expand All @@ -115,10 +120,11 @@ export class StaticSetProperty {
public emit(code: CodeMaker) {
emitInitialization(code);

code.openBlock(`_jsii_.NoOpRequest(_jsii_.NoOpApiRequest`);
code.line(`Class: "${this.parent.parent.name}",`);
code.line(`Method: "${this.parent.property.name}",`);
code.close(`})`);
code.open(`${JSII_SSET_FUNC}(`);
code.line(`"${this.parent.parent.fqn}",`);
code.line(`"${this.parent.property.name}",`);
code.line(`val,`);
code.close(`)`);
code.line(`return`);
}
}
Loading