Friday, July 10, 2015

Protobuf Annotations

We've had a module to deal with protobuf wire protocols for a while now (crack.protobuf), but you've always had to code your message serialization by hand.  Not any more!

I've just checked in crack.protobuf.ann, which is an annotation that allows you to define protobuf message definitions inline and generates the appropriate code.  So, for example, this:

 @protobuf {
    # Uncomment "debug" to emit the generated code to standard output with
    # line numbers.
    #debug

    message Bar {
        repeated string name = 1;
    }
}

Generates this:

class Bar @impl Message {
     Array[String] name = {};
     oper init() {}
     void serialize(ProtoWriter dst) {
         for (item :in this.name)
             dst.write(1, item);
         
     }
     void addField(Field field) {    
         if (field.id == 1) {
             this.name.append(field.getString());
             
         }
         
     }
     int cmp(Bar other) {    
         int rc;
         ((rc = cmp(this.name, other.name))
          );
         return rc;
     }
     int cmp(Object other) {
         if (o := Bar.cast(other))
             return cmp(o);
         else
             return Object.cmp(other);
     }
     uint makeHashVal() {    
         return makeHashVal(this.name);
     }
     @static Bar makeFromField(Field field) {
         Bar inst = {};
         field.readMessage(inst);
         return inst;
     }
     

 }

As protobuf generation goes, this isn't all that great.  For one thing, it would be much better if we could just generate crack code from the proto compiler like everything else and then we could use the same .proto files as everything else.  The implementation is also very incomplete.  It only supports the int32, int64, string and bytes types (and int64 is currently broken) and it doesn't support any protobuf syntax that is even slightly advanced.  That said, it still beats coding the serialization by hand.

No comments:

Post a Comment