protoclosure
Protocol Buffer interoperability
between Go's
protobuf and
closure-library's
goog.proto2
JavaScript implementation.
JS Usage
First, compile your *.pb.js file(s) with protoc:
$ cat src/simple/simple.proto
syntax = "proto2";
message Simple {
optional string foo = 1;
}
$ protoc --plugin=bin/protoc-js-go --js_out=. src/simple/simple.proto
Next, goog.require the Simple
package and use goog.json
to parse
and
serialize
the JSON based encodings. Also, consider adding
--define=goog.json.USE_NATIVE_JSON=true
to your compile for improved security
and runtime performance.
goog.provide('example');
goog.require('Simple');
goog.require('goog.json');
goog.require('goog.proto2.ObjectSerializer');
/**
* Example protobuf usage.
*/
example = function() {
// create a 'Hello World' message
var s = new Simple();
s.setFoo('Hello World');
// serialize the Simple message using the PBObject format
var serializer = new goog.proto2.ObjectSerializer();
var obj = serializer.serialize(s);
var jsonMsg = goog.json.serialize(obj);
// parse the PBObject format jsonMsg into a second protocol buffer message
var obj2 = goog.json.parse(jsonMsg);
var serializer2 = new goog.proto2.ObjectSerializer();
var s2 = /** @type {!Simple} */ (serializer2.deserialize(
Simple.getDescriptor(), obj2));
// ensure values are equal
if (s.getFoo() != s2.getFoo()) {
alert('Values are not equal: ' + s.getFoo() + '. ' + s2.getFoo() + '.');
}
};
Go Usage
First, compile a *.pb.go package from a *.proto file using protoc with the go
protobuf plugin:
$ protoc --plugin=bin/protoc-gen-go --go_out=. src/simple/simple.proto
$ # or if you want to generate both JS and Go with a single command
$ protoc --plugin=bin/protoc-gen-js --plugin=bin/protoc-gen-go --js_out=. \
--go_out=. src/simple/simple.proto
Next, import the simple
package and use protoclosure
to Marshal
and
Unmarshal
from the various JSON based encodings (see PBLite and PBObject
below).
package main
import (
"log"
"simple"
"github.com/golang/protobuf/proto"
"code.taxi/samegoal/protoclosure"
)
func main() {
s := &simple.Simple{}
s.Foo = proto.String("Hello World")
jsonMsg, err := protoclosure.MarshalObjectKeyTag(s)
if err != nil {
log.Fatal(err)
}
s2 := &simple.Simple{}
if err := protoclosure.UnmarshalObjectKeyTag(jsonMsg, s2); err != nil {
log.Fatal(err)
}
if *s.Foo != *s2.Foo {
log.Fatalf("Values not equal: %s. %s.", *s.Foo, *s2.Foo)
}
}
Go API documentation
Example message:
message Person {
optional int32 id = 1;
optional string name = 2;
optional string email = 3;
}
Example encoding:
[null,1,null,"user@example.com"]
Example encoding (zero-index):
[1,null,"user@example.com"]
Example message:
message Person {
optional int32 id = 1;
optional string name = 2;
optional string email = 3;
}
Example encoding (tag name):
{"id":1,"email":"user@example.com"}
Example encoding (tag number):
{"1":1,"3":"user@example.com"}
protoclosure development
$ # setup environment (GOPATH, etc)
$ go get code.taxi/samegoal/protoclosure
$ cd code.taxi/samegoal/protoclosure
$ # modify the source
$ go test -race
$ make # run vet/fmt/lint, prior to sending Pull Request
To regenerate unit test protobuf files:
$ protoc --go_out=. code.taxi/samegoal/protoclosure/test.proto
$ protoc --go_out=. code.taxi/samegoal/protoclosure/package_test.proto
$ mv code.taxi/samegoal/protoclosure/test.pb.go code.taxi/samegoal/protoclosure/test.pb/
$ mv code.taxi/samegoal/protoclosure/package_test.pb.go code.taxi/samegoal/protoclosure/package_test.pb/
Unlicensed example files
Please note that the test files test.proto
and package_test.proto
are not
included under the same BSD-style license as the rest of this package. These
files are not part of closure-library itself, but instead were
provided
by some helpful Googlers on closure-library-discuss. Since that time they have
been slightly modified as part of this project to remain current with upstream
changes to goog.proto2. The *.pb.js reference files which are generated based
upon these files are included in closure-library.
License
Use of this source code is governed by a BSD-style license that can be found in
the LICENSE file.
Special Thanks