otherlang.md 7.8 KB
Newer Older
Kenton Varda's avatar
Kenton Varda committed
1 2
---
layout: page
Kenton Varda's avatar
Kenton Varda committed
3
title: Other Languages
Kenton Varda's avatar
Kenton Varda committed
4 5 6 7
---

# Other Languages

8 9
Cap'n Proto's reference implementation is in C++.  Implementations in other languages are
maintained by respective authors and have not been reviewed by me
10 11 12
([@kentonv](https://github.com/kentonv)). Below are the implementations I'm aware
of. Some of these projects are more "ready" than others; please consult each
project's documentation for details.
13

14
##### Serialization + RPC
15

16
* [C++](cxx.html) by [@kentonv](https://github.com/kentonv)
17
* [Erlang](http://ecapnp.astekk.se/) by [@kaos](https://github.com/kaos)
Kenton Varda's avatar
Kenton Varda committed
18
* [Go](https://github.com/zombiezen/go-capnproto2) by [@zombiezen](https://github.com/zombiezen) (forked from [@glycerine](https://github.com/glycerine)'s serialization-only version, below)
19
* [Javascript (Node.js only)](https://github.com/capnproto/node-capnp) by [@kentonv](https://github.com/kentonv)
20
* [OCaml](https://github.com/capnproto/capnp-ocaml) by [@pelzlpj](https://github.com/pelzlpj) with [RPC](https://github.com/mirage/capnp-rpc) by [@talex5](https://github.com/talex5)
21
* [Python](http://capnproto.github.io/pycapnp/) by [@jparyani](https://github.com/jparyani)
22
* [Rust](https://github.com/dwrensha/capnproto-rust) by [@dwrensha](https://github.com/dwrensha)
23

24
##### Serialization only
25

26
* [C](https://github.com/opensourcerouting/c-capnproto) by [OpenSourceRouting](https://www.opensourcerouting.org/) / [@eqvinox](https://github.com/eqvinox) (originally by [@jmckaskill](https://github.com/jmckaskill))
27
* [C#](https://github.com/mgravell/capnproto-net) by [@mgravell](https://github.com/mgravell)
28
* [D](https://github.com/capnproto/capnproto-dlang) by [@ThomasBrixLarsen](https://github.com/ThomasBrixLarsen)
29
* [Go](https://github.com/glycerine/go-capnproto) by [@glycerine](https://github.com/glycerine) (originally by [@jmckaskill](https://github.com/jmckaskill))
30
* [Java](https://github.com/capnproto/capnproto-java/) by [@dwrensha](https://github.com/dwrensha)
31 32
* [Javascript](https://github.com/popham/capnp-js-base) by [@popham](https://github.com/popham)
* [Javascript](https://github.com/jscheid/capnproto-js) (older, abandoned) by [@jscheid](https://github.com/jscheid)
33
* [Lua](https://github.com/cloudflare/lua-capnproto) by [CloudFlare](http://www.cloudflare.com/) / [@calio](https://github.com/calio)
34
* [Nim](https://github.com/zielmicha/capnp.nim) by [@zielmicha](https://github.com/zielmicha)
Kenton Varda's avatar
Kenton Varda committed
35
* [Ruby](https://github.com/cstrahan/capnp-ruby) by [@cstrahan](https://github.com/cstrahan)
36
* [Scala](https://github.com/katis/capnp-scala) by [@katis](https://github.com/katis)
Kenton Varda's avatar
Kenton Varda committed
37

38
##### Tools
Kenton Varda's avatar
Kenton Varda committed
39

40 41 42 43
These are other misc projects related to Cap'n Proto that are not actually implementations in
new languages.

* [Common Test Framework](https://github.com/kaos/capnp_test) by [@kaos](https://github.com/kaos)
44 45
* [Sublime Syntax Highlighting](https://github.com/joshuawarner32/capnproto-sublime) by
  [@joshuawarner32](https://github.com/joshuawarner32)
46 47
* [Vim Syntax Highlighting](https://github.com/peter-edge/vim-capnp) by [@peter-edge](https://github.com/peter-edge)
  (originally by [@cstrahan](https://github.com/cstrahan))
48
* [Wireshark Dissector Plugin](https://github.com/kaos/wireshark-plugins) by [@kaos](https://github.com/kaos)
49 50
* [VS Code Syntax Highlighter](https://marketplace.visualstudio.com/items?itemName=xmonader.vscode-capnp) by [@xmonader](https://github.com/xmonader)
* [IntelliJ Syntax Highlighter](https://github.com/xmonader/sercapnp) by [@xmonader](https://github.com/xmonader)
51 52 53 54

## Contribute Your Own!

We'd like to support many more languages in the future!
Kenton Varda's avatar
Kenton Varda committed
55 56 57

If you'd like to own the implementation of Cap'n Proto in some particular language,
[let us know](https://groups.google.com/group/capnproto)!
58 59 60 61

**You should e-mail the list _before_ you start hacking.**  We don't bite, and we'll probably have
useful tips that will save you time.  :)

62
**Do not implement your own schema parser.**  The schema language is more complicated than it
63 64 65 66
looks, and the algorithm to determine offsets of fields is subtle.  If you reuse the official
parser, you won't risk getting these wrong, and you won't have to spend time keeping your parser
up-to-date.  In fact, you can still write your code generator in any language you want, using
compiler plugins!
67 68 69

### How to Write Compiler Plugins

70 71 72 73 74
The Cap'n Proto tool, `capnp`, does not actually know how to generate code.  It only parses schemas,
then hands the parse tree off to another binary -- known as a "plugin" -- which generates the code.
Plugins are independent executables (written in any language) which read a description of the
schema from standard input and then generate the necessary code.  The description is itself a
Cap'n Proto message, defined by
75
[schema.capnp](https://github.com/sandstorm-io/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp).
Kenton Varda's avatar
Kenton Varda committed
76
Specifically, the plugin receives a `CodeGeneratorRequest`, using
77
[standard serialization](encoding.html#serialization-over-a-stream)
Kenton Varda's avatar
Kenton Varda committed
78 79
(not packed).  (Note that installing the C++ runtime causes schema.capnp to be placed in
`$PREFIX/include/capnp` -- `/usr/local/include/capnp` by default).
80 81 82 83 84

Of course, because the input to a plugin is itself in Cap'n Proto format, if you write your
plugin directly in the language you wish to support, you may have a bootstrapping problem:  you
somehow need to generate code for `schema.capnp` before you write your code generator.  Luckily,
because of the simplicity of the Cap'n Proto format, it is generally not too hard to do this by
85 86
hand.  Remember that you can use `capnp compile -ocapnp schema.capnp` to get a dump of the sizes
and offsets of all structs and fields defined in the file.
87

88 89 90 91
`capnp compile` normally looks for plugins in `$PATH` with the name `capnpc-[language]`, e.g.
`capnpc-c++` or `capnpc-capnp`.  However, if the language name given on the command line contains
a slash character, `capnp` assumes that it is an exact path to the plugin executable, and does not
search `$PATH`.  Examples:
92 93

    # Searches $PATH for executable "capnpc-mylang".
94
    capnp compile -o mylang addressbook.capnp
95 96

    # Uses plugin executable "myplugin" from the current directory.
97
    capnp compile -o ./myplugin addressbook.capnp
98 99 100 101

If the user specifies an output directory, the compiler will run the plugin with that directory
as the working directory, so you do not need to worry about this.

102
For examples of plugins, take a look at
103 104
[capnpc-capnp](https://github.com/sandstorm-io/capnproto/blob/master/c%2B%2B/src/capnp/compiler/capnpc-capnp.c%2B%2B)
or [capnpc-c++](https://github.com/sandstorm-io/capnproto/blob/master/c%2B%2B/src/capnp/compiler/capnpc-c%2B%2B.c%2B%2B).
Kenton Varda's avatar
Kenton Varda committed
105 106 107

### Supporting Dynamic Languages

108 109 110
Dynamic languages have no compile step.  This makes it difficult to work `capnp compile` into the
workflow for such languages.  Additionally, dynamic languages are often scripting languages that do
not support pointer arithmetic or any reasonably-performant alternative.
Kenton Varda's avatar
Kenton Varda committed
111 112 113

Fortunately, dynamic languages usually have facilities for calling native code.  The best way to
support Cap'n Proto in a dynamic language, then, is to wrap the C++ library, in particular the
114
[C++ dynamic API](cxx.html#dynamic-reflection).  This way you get reasonable performance while
Kenton Varda's avatar
Kenton Varda committed
115 116
still avoiding the need to generate any code specific to each schema.

Kenton Varda's avatar
Kenton Varda committed
117 118 119 120 121 122 123 124 125
To parse the schema files, use the `capnp::SchemaParser` class (defined in `capnp/schema-parser.h`).
This way, schemas are loaded at the same time as all the rest of the program's code -- at startup.
An advanced implementation might consider caching the compiled schemas in binary format, then
loading the cached version using `capnp::SchemaLoader`, similar to the way e.g. Python caches
compiled source files as `.pyc` bytecode, but that's up to you.

### Testing Your Implementation

The easiest way to test that you've implemented the spec correctly is to use the `capnp` tool
126 127
to [encode](capnp-tool.html#encoding-messages) test inputs and
[decode](capnp-tool.html#decoding-messages) outputs.