--- title: Autogenerating Cwtch Bindings description: "In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification." slug: autobindings tags: [cwtch, cwtch-stable, bindings, autobindings, libcwtch] image: /img/devlog8_small.png hide_table_of_contents: false toc_max_heading_level: 4 authors: - name: Sarah Jamie Lewis title: Executive Director, Open Privacy Research Society image_url: /img/sarah.jpg --- The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to **automatically generate** these bindings: [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings). This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the [path to Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable). ![](/img/devlog8.png) ## A Brief History of Cwtch Bindings Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by [therecipe/qt](https://github.com/therecipe/qt). However, after encountering numerous crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework. As part of early prototyping efforts for Flutter we built out a first version of [libCwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go), and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings. This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular [experimental features](https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape) - handle settings, [duplication of logic between Cwtch and libCwtch-go](https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings), and [special behaviour in libCwtch-go that better belongs in the core Cwtch library](https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go). As part of a broader effort to [refine the Cwtch API in preparation for Cwtch Stable](https://docs.cwtch.im/blog/cwtch-stable-api-design) we have taken the opportunity to fix many of these problems. ## Cwtch Autobindings The current `lib.go` file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the `BlockContact` API implementation is: ``` //export c_BlockContact func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) { BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id)) } func BlockContact(profileOnion string, conversationID int) { profile := application.GetPeer(profileOnion) if profile != nil { profile.BlockConversation(conversationID) } } ``` All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively. In the new [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings) we reduce these multiple lines to [a single one](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19): profile BlockConversation conversation Defining a `profile`-level function, called `BlockConversation` which takes in a single parameter of type `conversation`. Using a similar boilerplate-reduction for the reset of `lib.go` yields [5-basic function prototypes](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format): * Application-level functions e.g. `CreateProfile` * Profile-level functions e.g. `BlockConversation` * Profile-level functions that return data e.g. `GetMessage` * Experimental Profile-level feature functions e.g. `DownloadFile` * Experimental Profile-level feature functions that return data e.g. `ShareFile` Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be [described in fewer than 50 lines, including comments](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec). Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.). ## Next Steps Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout: * **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)** (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on `cwtch-server`). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features. * **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart-side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs) * **Documentation generation**: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im). * **Cwtch API**: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the [Cwtch Stable API redesign](https://docs.cwtch.im/blog/cwtch-stable-api-design). In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond. ## Help us go further! We couldn't do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy). If you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer. Donations of **$5 or more** can opt to receive stickers as a thank-you gift! For more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/). ![A Photo of Cwtch Stickers](/img/stickers-new.jpg)