WebAssembly: Auto-generating Go bindings for javascript/DOM from the Web Standards.

674 views
Skip to first unread message

Chris FractalBach

unread,
Dec 28, 2018, 7:16:22 AM12/28/18
to golang-nuts
This is in the context of compiling Go to webassembly that will be used with javascript.


Currently:

We have`syscall/js` which has stuff like this:
```go
js.Global().Get("document").Call("createElement", "div")
```

What it could be:
```go
js.document.createElement("div")
```



Why?

This would make writing stuff for webassembly WAY easier.
Auto-generating it would allow it to update definitions whenever the standards
are updated.  Which would make it easier to maintain.

Also, if there's going to be significant usage of
Go -> webassembly -> web browser and javascript
then having all the types and definitions auto-generated would save on tons
of boilerplate abstractions that people will inevitably create for their own sanity.

Advantages:
- more natural to use
- more readable
- type safe

Disadvantages:
- less flexible
- when the APIs are updated, it might result in loss of backwards-compatibility




How?

WebIDL --> Go source code





Technical reports published by the W3C that include programming language interfaces have typically been described using the Object Management Group’s Interface Definition Language (IDL) [OMGIDL]. The IDL provides a means to describe these interfaces in a language independent manner. Usually, additional language binding appendices are included in such documents which detail how the interfaces described with the IDL correspond to constructs in the given language.





A Possible Conversion:

From WebIDL:
```
[Exposed=Window]
interface Paint { };


[Exposed=Window]
interface SolidColor : Paint {
  attribute double red;
  attribute double green;
  attribute double blue;
};


[Exposed=Window]
interface Pattern : Paint {
  attribute DOMString imageURL;
};


[Exposed=Window, Constructor]
interface GraphicalWindow {
  readonly attribute unsigned long width;
  readonly attribute unsigned long height;


  attribute Paint currentPaint;


  void drawRectangle(double x, double y, double width, double height);


  void drawText(double x, double y, DOMString text);
};

```



To Go:

This is probably not the best way to do it, but is an example of how it might look.

type Paint struct {}


type
SolidColor struct {
 
Red   float64
 
Green float64
 
Blue  float64
}


type
GraphicalWindow struct {
 width        uint32
 height       uint32
 
CurrentPaint Paint
}


func
(gw *GraphicalWindow) drawRectangle(x, y, width, height float64) {
   
// syscall
}


func
(gw *GraphicalWindow) drawText(x, y float64, text string) {
   
// syscall
}






I know there are some existing examples of Go bindings for DOM, 
but I don't think they are auto-generated from WebIDL,
Which I imagine would be easier to maintain in the long-run.




Anybody have thoughts on this?




Agniva De Sarker

unread,
Dec 29, 2018, 12:32:18 AM12/29/18
to golang-nuts
Makes sense. This has been brought up before in the #webassembly channel. Don't remember what the conclusion was. But please feel free to drop in and throw some ideas around.

Demand for a proper DOM API has been growing. And I think auto-generating from WebIDL files are a great way to get started.

Chris FractalBach

unread,
Jan 1, 2019, 2:49:18 PM1/1/19
to golang-nuts
Are the # channels on slack?

Paul Jolly

unread,
Jan 2, 2019, 6:03:08 AM1/2/19
to Chris FractalBach, golang-nuts
Yes; see https://github.com/golang/go/wiki#the-go-community for
details on how to join.

On Tue, 1 Jan 2019 at 19:49, Chris FractalBach <fract...@gmail.com> wrote:
>
> Are the # channels on slack?
>
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Martin Juhlin

unread,
Feb 24, 2019, 9:16:55 AM2/24/19
to golang-nuts
Hi,

I have started to work on DOM binding based on WebIDL and a binding generator. I don't have full WebIDL support yet, but it does process idl from about 80 specifications. See https://gowebapi.github.io for more details.

   Martin

Tyler Compton

unread,
Feb 24, 2019, 7:44:40 PM2/24/19
to Martin Juhlin, golang-nuts
Hi Martin,

This is really exciting work! I would definitely recommend posting this as an announcement in its own thread, I'm sure a lot of people are looking for something like this. Thanks for taking the initiative!

Paul Jolly

unread,
Feb 25, 2019, 1:41:20 AM2/25/19
to Martin Juhlin, golang-nuts
I have started to work on DOM binding based on WebIDL and a binding generator. I don't have full WebIDL support yet, but it does process idl from about 80 specifications. See https://gowebapi.github.io for more details.

Hi Martin,

I'd like to second Tyler's suggestion that you start a new thread, very exciting!

My question is: to what extent is your WebIDL parser and AST equivalent separate from the Go-WASM target code you are generating? 

Reason being, I'd like the use the IDL specs to generate Go code for React bindings, replacing currently hand-written code. This will likely require some sort of tweaks/annotations atop WebIDL for any React vagaries, hence I'm wondering to what extent the WebIDL interface is reusable.

Thanks,


Paul

Martin Juhlin

unread,
Feb 25, 2019, 4:03:51 PM2/25/19
to Paul Jolly, golang-nuts
Hi,

The code is Parser is actually a fork that I did some modifications to (like line number). Can be found at https://github.com/gowebapi/webidlparser

The main flow is currently:
* Parse with webidlparser to get a AST tree.
* Convert into internal types in “github.com/gowebapi/webidl-bind/types”.
* Applying transformation like adding Go packages in “github.com/gowebapi/webidl-bind/transform”.
* And finally the generation step in “github.com/gowebapi/webidl-bind/gowasm”.

To use WebIDL to create binding for React.js can be problematic as the standard as-is doesn’t support for javascript modules. The IDL standard that WebIDL based on however does. It uses C++ like syntax (foo::bar) inside “namespace” block. It’s probably not hard to solve.

In the current handwritten library, how is the interaction with JSX solved? It feels like that normal react.js code is compiled.

    Martin

Reply all
Reply to author
Forward
0 new messages