Merge pull request #1413 from haberman/updateupb
Updated upb: JSON parser now accepts both camelCase and original case, and flag to choose on output.
This commit is contained in:
commit
ca9bbd71d5
@ -80,7 +80,6 @@ JsonInput.Int32FieldMaxFloatValue.JsonOutput
|
||||
JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
|
||||
JsonInput.Int32FieldMinFloatValue.JsonOutput
|
||||
JsonInput.Int32FieldMinFloatValue.ProtobufOutput
|
||||
JsonInput.Int32FieldMinValue.JsonOutput
|
||||
JsonInput.Int32FieldStringValue.JsonOutput
|
||||
JsonInput.Int32FieldStringValue.ProtobufOutput
|
||||
JsonInput.Int32FieldStringValueEscaped.JsonOutput
|
||||
@ -125,7 +124,6 @@ JsonInput.OptionalUint64Wrapper.ProtobufOutput
|
||||
JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
|
||||
JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
|
||||
JsonInput.OriginalProtoFieldName.JsonOutput
|
||||
JsonInput.OriginalProtoFieldName.ProtobufOutput
|
||||
JsonInput.PrimitiveRepeatedField.JsonOutput
|
||||
JsonInput.PrimitiveRepeatedField.ProtobufOutput
|
||||
JsonInput.RepeatedBoolWrapper.JsonOutput
|
||||
|
@ -32,23 +32,25 @@ documentation may be found in the RubyDoc comments (`call-seq` tags) in the
|
||||
source, and we plan to release separate, more detailed, documentation at a
|
||||
later date.
|
||||
|
||||
require 'google/protobuf'
|
||||
```ruby
|
||||
require 'google/protobuf'
|
||||
|
||||
# generated from my_proto_types.proto with protoc:
|
||||
# $ protoc --ruby_out=. my_proto_types.proto
|
||||
require 'my_proto_types'
|
||||
# generated from my_proto_types.proto with protoc:
|
||||
# $ protoc --ruby_out=. my_proto_types.proto
|
||||
require 'my_proto_types'
|
||||
|
||||
mymessage = MyTestMessage.new(:field1 => 42, :field2 => ["a", "b", "c"])
|
||||
mymessage.field1 = 43
|
||||
mymessage.field2.push("d")
|
||||
mymessage.field3 = SubMessage.new(:foo => 100)
|
||||
mymessage = MyTestMessage.new(:field1 => 42, :field2 => ["a", "b", "c"])
|
||||
mymessage.field1 = 43
|
||||
mymessage.field2.push("d")
|
||||
mymessage.field3 = SubMessage.new(:foo => 100)
|
||||
|
||||
encoded_data = MyTestMessage.encode(mymessage)
|
||||
decoded = MyTestMessage.decode(encoded_data)
|
||||
assert decoded == mymessage
|
||||
encoded_data = MyTestMessage.encode(mymessage)
|
||||
decoded = MyTestMessage.decode(encoded_data)
|
||||
assert decoded == mymessage
|
||||
|
||||
puts "JSON:"
|
||||
puts MyTestMessage.encode_json(mymessage)
|
||||
puts "JSON:"
|
||||
puts MyTestMessage.encode_json(mymessage)
|
||||
```
|
||||
|
||||
Installation from Source (Building Gem)
|
||||
---------------------------------------
|
||||
|
@ -255,6 +255,10 @@ void Descriptor_free(void* _self) {
|
||||
upb_handlers_unref(self->json_serialize_handlers,
|
||||
&self->json_serialize_handlers);
|
||||
}
|
||||
if (self->json_serialize_handlers_preserve) {
|
||||
upb_handlers_unref(self->json_serialize_handlers_preserve,
|
||||
&self->json_serialize_handlers_preserve);
|
||||
}
|
||||
xfree(self);
|
||||
}
|
||||
|
||||
@ -278,6 +282,7 @@ VALUE Descriptor_alloc(VALUE klass) {
|
||||
self->json_fill_method = NULL;
|
||||
self->pb_serialize_handlers = NULL;
|
||||
self->json_serialize_handlers = NULL;
|
||||
self->json_serialize_handlers_preserve = NULL;
|
||||
self->typeclass_references = rb_ary_new();
|
||||
return ret;
|
||||
}
|
||||
|
@ -1130,13 +1130,23 @@ static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
|
||||
return desc->pb_serialize_handlers;
|
||||
}
|
||||
|
||||
static const upb_handlers* msgdef_json_serialize_handlers(Descriptor* desc) {
|
||||
if (desc->json_serialize_handlers == NULL) {
|
||||
desc->json_serialize_handlers =
|
||||
upb_json_printer_newhandlers(
|
||||
desc->msgdef, &desc->json_serialize_handlers);
|
||||
static const upb_handlers* msgdef_json_serialize_handlers(
|
||||
Descriptor* desc, bool preserve_proto_fieldnames) {
|
||||
if (preserve_proto_fieldnames) {
|
||||
if (desc->json_serialize_handlers == NULL) {
|
||||
desc->json_serialize_handlers =
|
||||
upb_json_printer_newhandlers(
|
||||
desc->msgdef, true, &desc->json_serialize_handlers);
|
||||
}
|
||||
return desc->json_serialize_handlers;
|
||||
} else {
|
||||
if (desc->json_serialize_handlers_preserve == NULL) {
|
||||
desc->json_serialize_handlers_preserve =
|
||||
upb_json_printer_newhandlers(
|
||||
desc->msgdef, false, &desc->json_serialize_handlers_preserve);
|
||||
}
|
||||
return desc->json_serialize_handlers_preserve;
|
||||
}
|
||||
return desc->json_serialize_handlers;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1181,16 +1191,33 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
|
||||
*
|
||||
* Encodes the given message object into its serialized JSON representation.
|
||||
*/
|
||||
VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
|
||||
VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
||||
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
||||
Descriptor* desc = ruby_to_Descriptor(descriptor);
|
||||
|
||||
VALUE msg_rb;
|
||||
VALUE preserve_proto_fieldnames = Qfalse;
|
||||
stringsink sink;
|
||||
|
||||
if (argc < 1 || argc > 2) {
|
||||
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
||||
}
|
||||
|
||||
msg_rb = argv[0];
|
||||
|
||||
if (argc == 2) {
|
||||
VALUE hash_args = argv[1];
|
||||
if (TYPE(hash_args) != T_HASH) {
|
||||
rb_raise(rb_eArgError, "Expected hash arguments.");
|
||||
}
|
||||
preserve_proto_fieldnames = rb_hash_lookup2(
|
||||
hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
|
||||
}
|
||||
|
||||
stringsink_init(&sink);
|
||||
|
||||
{
|
||||
const upb_handlers* serialize_handlers =
|
||||
msgdef_json_serialize_handlers(desc);
|
||||
msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
|
||||
upb_json_printer* printer;
|
||||
stackenv se;
|
||||
VALUE ret;
|
||||
|
@ -475,7 +475,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
||||
rb_define_singleton_method(klass, "decode", Message_decode, 1);
|
||||
rb_define_singleton_method(klass, "encode", Message_encode, 1);
|
||||
rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1);
|
||||
rb_define_singleton_method(klass, "encode_json", Message_encode_json, 1);
|
||||
rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
|
||||
rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
|
||||
|
||||
return klass;
|
||||
|
@ -115,6 +115,7 @@ struct Descriptor {
|
||||
const upb_json_parsermethod* json_fill_method;
|
||||
const upb_handlers* pb_serialize_handlers;
|
||||
const upb_handlers* json_serialize_handlers;
|
||||
const upb_handlers* json_serialize_handlers_preserve;
|
||||
// Handlers hold type class references for sub-message fields directly in some
|
||||
// cases. We need to keep these rooted because they might otherwise be
|
||||
// collected.
|
||||
@ -498,7 +499,7 @@ VALUE Message_descriptor(VALUE klass);
|
||||
VALUE Message_decode(VALUE klass, VALUE data);
|
||||
VALUE Message_encode(VALUE klass, VALUE msg_rb);
|
||||
VALUE Message_decode_json(VALUE klass, VALUE data);
|
||||
VALUE Message_encode_json(VALUE klass, VALUE msg_rb);
|
||||
VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass);
|
||||
|
||||
VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1161,7 +1161,12 @@ module BasicTest
|
||||
return if RUBY_PLATFORM == "java"
|
||||
m = MapMessage.new(:map_string_int32 => {"a" => 1})
|
||||
expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
|
||||
expected_preserve = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
|
||||
assert MapMessage.encode_json(m) == expected
|
||||
|
||||
json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
|
||||
assert json == expected_preserve
|
||||
|
||||
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
|
||||
assert m == m2
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user