diff options
-rw-r--r-- | DESIGN.md | 33 | ||||
-rw-r--r-- | README.md | 130 |
2 files changed, 113 insertions, 50 deletions
@@ -2,9 +2,6 @@ μpb Design ---------- -**NOTE:** the design described here is being implemented currently, but is not -yet complete. The repo is in heavy transition right now. - μpb has the following design goals: - C89 compatible. @@ -62,22 +59,14 @@ link μpb will never need to worry about this. TODO ---- -The current state of the repo is quite different than what is described above. -Here are the major items that need to be implemented. - -1. implement the core generic protobuf binary encoder/decoder that uses a - `upb_msglayout*`. -2. remove all mention of handlers, sink, etc. from core into their own module. - All of the handlers stuff needs substantial revision, but moving it out of - core is the first priority. -3. move all of the def/refcounted stuff out of core. The defs also need - substantial revision, but moving them out of core is the first priority. -4. revise our generated code until it is in a state where we feel comfortable - committing to API/ABI stability for it. This may involve moving different - parts of the generated code into separate files, like keeping the serialized - descriptor in a separate file from the compact msglayout. -5. revise all of the existing encoders/decoders and handlers. We probably - will want to keep handlers, since they let us decouple encoders/decoders - from `upb_msg`, but we need to simplify all of that a LOT. Likely we will - want to make handlers only per-message instead of per-field, except for - variable-length fields. +1. revise our generated code until it is in a state where we feel comfortable + committing to API/ABI stability for it. In particular there is an open + question of whether non-ABI-compatible field accesses should have a + fastpath different from the ABI-compatible field access. +1. Add missing features (maps, extensions, unknown fields). +1. Flesh out C++ wrappers. +1. *(lower-priority)*: revise all of the existing encoders/decoders and + handlers. We probably will want to keep handlers, since they let us decouple + encoders/decoders from `upb_msg`, but we need to simplify all of that a LOT. + Likely we will want to make handlers only per-message instead of per-field, + except for variable-length fields. @@ -1,53 +1,127 @@ # μpb - a small protobuf implementation in C -[![Build Status](https://travis-ci.org/google/upb.svg?branch=master)](https://travis-ci.org/google/upb) -[![Coverage Status](https://img.shields.io/coveralls/google/upb.svg)](https://coveralls.io/r/google/upb?branch=master) - -μpb is a small protobuf implementation written in C. +|Platform|Build Status| +|--------|------------| +|macOS|[![Build Status](https://storage.googleapis.com/upb-kokoro-results/status-badge/macos.png)](https://fusion.corp.google.com/projectanalysis/summary/KOKORO/prod%3Aupb%2Fmacos%2Fcontinuous)| +|ubuntu|[![Build Status](https://storage.googleapis.com/upb-kokoro-results/status-badge/ubuntu.png)](https://fusion.corp.google.com/projectanalysis/summary/KOKORO/prod%3Aupb%2Fubuntu%2Fcontinuous)| + +μpb (often written 'upb') is a small protobuf implementation written in C. + +upb generates a C API for creating, parsing, and serializing messages +as declared in `.proto` files. upb is heavily arena-based: all +messages always live in an arena (note: the arena can live in stack or +static memory if desired). Here is a simple example: + +```c +#include "conformance/conformance.upb.h" + +void foo(const char* data, size_t size) { + upb_arena *arena; + + /* Generated message type. */ + conformance_ConformanceRequest *request; + conformance_ConformanceResponse *response; + + arena = upb_arena_new(); + request = conformance_ConformanceRequest_parse(data, size, arena); + response = conformance_ConformanceResponse_new(arena); + + switch (conformance_ConformanceRequest_payload_case(request)) { + case conformance_ConformanceRequest_payload_protobuf_payload: { + upb_strview payload = conformance_ConformanceRequest_protobuf_payload(request); + // ... + break; + } + + case conformance_ConformanceRequest_payload_NOT_SET: + fprintf(stderr, "conformance_upb: Request didn't have payload.\n"); + break; + + default: { + static const char msg[] = "Unsupported input format."; + conformance_ConformanceResponse_set_skipped( + response, upb_strview_make(msg, sizeof(msg))); + break; + } + } + + /* Frees all messages on the arena. */ + upb_arena_free(arena); +} +``` API and ABI are both subject to change! Please do not distribute as a shared library for this reason (for now at least). -## Building the core libraries +## Using upb in your project -The core libraries are pure C99 and have no dependencies. +Currently only Bazel is supported (CMake support is partial and incomplete +but full CMake support is an eventual goal). - $ make +To use upb in your Bazel project, first add upb to your `WORKSPACE` file, +either as a `git_repository()` or as a `new_local_repository()` with a +Git Submodule: -This will create a separate C library for each core library -in `lib/`. They are built separately to help your binaries -slim, so you don't need to link in things you neither want -or need. +```python +# Add this to your WORKSPACE file. +git_repository( + name = "upb", + remote = "https://github.com/protocolbuffers/upb.git", + # You may want to substitute a more recent commit here. + commit = "d5af87d06bbe3abad66970ce9c7ae0a7de8bb3c6", +) +``` -Other useful targets: +Then in your BUILD file you can add `upb_proto_library()` rules that +generate code for a corresponding `proto_library()` rule. For +example: - $ make tests - $ make test +```python +# Add this to your BUILD file. +load(":upb_proto_library.bzl", "upb_proto_library") -## C and C++ API +proto_library( + name = "foo_proto", + srcs = ["foo.proto"], +) -The public C/C++ API is defined by all of the .h files in -`upb/` except `.int.h` files (which are internal-only). +upb_proto_library( + name = "foo_upbproto", + deps = [":foo_proto"], +) -## Lua bindings +cc_library( + name = "lib_that_uses_protos", + srcs = ["lib_that_uses_protos.cc"], + deps = [":foo_upbproto"], +) +``` -Lua bindings provide μpb's functionality to Lua programs. -The bindings target Lua 5.1, Lua 5.2, LuaJIT, and (soon) Lua 5.3. +Then in your `.c` file you can #include the generated header: -To build the Lua bindings, the Lua libraries must be installed. Once -they are installed, run: +```c +#include "foo.upb.h" - $ make lua +/* Insert code that uses generated types. */ +``` -Note that if the Lua headers are not in a standard place, you may -need to pass custom flags: +## Old "handlers" interfaces - $ make lua USER_CPPFLAGS=`pkg-config lua5.2 --cflags` +This library contains several semi-deprecated interfaces (see BUILD +file for more info about which interfaces are deprecated). These +deprecated interfaces are still used in some significant projects, +such as the Ruby and PHP C bindings for protobuf in the [main protobuf +repo](https://github.com/protocolbuffers/protobuf). The goal is to +migrate the Ruby/PHP bindings to use the newer, simpler interfaces +instead. Please do not use the old interfaces in new code. -To test the Lua bindings: +## Lua bindings - $ make testlua +This repo has some Lua bindings for the core library. These are +experimental and very incomplete. These are currently included in +order to validate that the C API is suitable for wrapping. As the +project matures these Lua bindings may become publicly available. ## Contact |