roc-streaming / roc-toolkit

Real-time audio streaming over the network.
https://roc-streaming.org
Mozilla Public License 2.0
1.03k stars 205 forks source link

Create Python script that generates Go and Java files for enum declarations #574

Closed gavv closed 9 months ago

gavv commented 9 months ago

We have a C library and Go and Java bindings for it.

Bindings are created manually. This is mostly fine and intended.

However, there is one place where we would like to use code generation instead. C library defines quite a lot of enums, and these enums are replicated one-to-one in bindings.

It would be nice to implement a script that automatically parses enums in C library and generates corresponding Go and Java files.

The easiest way to parse C declarations is to run doxygen build, which will produce XML file with all C API declarations. Then we can find enum declarations in that file.

Enums are declared in these headers:

After building documentation, as described here, Doxygen-generated XML files will be located in build/docs/public_api/xml.

For example, there is roc_format enum with ROC_FORMAT_PCM_FLOAT32 value, and here is corresponding nodes in XML:

       <memberdef kind="enum" id="config_8h_1ac24a6637fefa48d61bb8631c25bde919" prot="public" static="n     o" strong="no">
         <type></type>
         <name>roc_format</name>
         <enumvalue id="config_8h_1ac24a6637fefa48d61bb8631c25bde919aa851fa1a679b2df37b113fefe53b98e1"      prot="public">
           <name>ROC_FORMAT_PCM_FLOAT32</name>
           <initializer>= 1</initializer>
           <briefdescription>
 <para>PCM floats. </para>
           </briefdescription>
           <detaileddescription>
 <para>Uncompressed samples coded as 32-bit native-endian floats in range [-1; 1]. Channels are interle     aved, e.g. two channels are encoded as &quot;L R L R ...&quot;. </para>
           </detaileddescription>
         </enumvalue>

And here is what we should generate (kind of):

In go, all enums are currently in same file (config.go), and in java, each enum is in its own file. Currently they're updated manually. And now we want to replace this hand-written definitions with generated code.

Generator should produce something similar to what exists currently. It should:

Since one class per file is preferred for Java, for simplicity we can use same approach for Go as well.

We should keep in mind that in future more bindings may be added, and it should be feasible to extend generator to support more output languages.

We use Python for scripting, so let's use it for generator as well. The script should be added here: https://github.com/roc-streaming/roc-toolkit/tree/develop/scripts

We'll need 3 pull requests: