Browse Source

Merge pull request #1413 from haberman/updateupb

Updated upb: JSON parser now accepts both camelCase and original case, and flag to choose on output.
Joshua Haberman 9 years ago
parent
commit
ca9bbd71d5

+ 0 - 2
conformance/failure_list_ruby.txt

@@ -80,7 +80,6 @@ JsonInput.Int32FieldMaxFloatValue.JsonOutput
 JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
 JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
 JsonInput.Int32FieldMinFloatValue.JsonOutput
 JsonInput.Int32FieldMinFloatValue.JsonOutput
 JsonInput.Int32FieldMinFloatValue.ProtobufOutput
 JsonInput.Int32FieldMinFloatValue.ProtobufOutput
-JsonInput.Int32FieldMinValue.JsonOutput
 JsonInput.Int32FieldStringValue.JsonOutput
 JsonInput.Int32FieldStringValue.JsonOutput
 JsonInput.Int32FieldStringValue.ProtobufOutput
 JsonInput.Int32FieldStringValue.ProtobufOutput
 JsonInput.Int32FieldStringValueEscaped.JsonOutput
 JsonInput.Int32FieldStringValueEscaped.JsonOutput
@@ -125,7 +124,6 @@ JsonInput.OptionalUint64Wrapper.ProtobufOutput
 JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
 JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
 JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
 JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
 JsonInput.OriginalProtoFieldName.JsonOutput
 JsonInput.OriginalProtoFieldName.JsonOutput
-JsonInput.OriginalProtoFieldName.ProtobufOutput
 JsonInput.PrimitiveRepeatedField.JsonOutput
 JsonInput.PrimitiveRepeatedField.JsonOutput
 JsonInput.PrimitiveRepeatedField.ProtobufOutput
 JsonInput.PrimitiveRepeatedField.ProtobufOutput
 JsonInput.RepeatedBoolWrapper.JsonOutput
 JsonInput.RepeatedBoolWrapper.JsonOutput

+ 15 - 13
ruby/README.md

@@ -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
 source, and we plan to release separate, more detailed, documentation at a
 later date.
 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)
 Installation from Source (Building Gem)
 ---------------------------------------
 ---------------------------------------

+ 5 - 0
ruby/ext/google/protobuf_c/defs.c

@@ -255,6 +255,10 @@ void Descriptor_free(void* _self) {
     upb_handlers_unref(self->json_serialize_handlers,
     upb_handlers_unref(self->json_serialize_handlers,
                        &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);
   xfree(self);
 }
 }
 
 
@@ -278,6 +282,7 @@ VALUE Descriptor_alloc(VALUE klass) {
   self->json_fill_method = NULL;
   self->json_fill_method = NULL;
   self->pb_serialize_handlers = NULL;
   self->pb_serialize_handlers = NULL;
   self->json_serialize_handlers = NULL;
   self->json_serialize_handlers = NULL;
+  self->json_serialize_handlers_preserve = NULL;
   self->typeclass_references = rb_ary_new();
   self->typeclass_references = rb_ary_new();
   return ret;
   return ret;
 }
 }

+ 36 - 9
ruby/ext/google/protobuf_c/encode_decode.c

@@ -1130,13 +1130,23 @@ static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
   return desc->pb_serialize_handlers;
   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.
  * 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);
   VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
   Descriptor* desc = ruby_to_Descriptor(descriptor);
   Descriptor* desc = ruby_to_Descriptor(descriptor);
-
+  VALUE msg_rb;
+  VALUE preserve_proto_fieldnames = Qfalse;
   stringsink sink;
   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);
   stringsink_init(&sink);
 
 
   {
   {
     const upb_handlers* serialize_handlers =
     const upb_handlers* serialize_handlers =
-        msgdef_json_serialize_handlers(desc);
+        msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
     upb_json_printer* printer;
     upb_json_printer* printer;
     stackenv se;
     stackenv se;
     VALUE ret;
     VALUE ret;

+ 1 - 1
ruby/ext/google/protobuf_c/message.c

@@ -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, "decode", Message_decode, 1);
   rb_define_singleton_method(klass, "encode", Message_encode, 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, "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);
   rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
 
 
   return klass;
   return klass;

+ 2 - 1
ruby/ext/google/protobuf_c/protobuf.h

@@ -115,6 +115,7 @@ struct Descriptor {
   const upb_json_parsermethod* json_fill_method;
   const upb_json_parsermethod* json_fill_method;
   const upb_handlers* pb_serialize_handlers;
   const upb_handlers* pb_serialize_handlers;
   const upb_handlers* json_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
   // Handlers hold type class references for sub-message fields directly in some
   // cases. We need to keep these rooted because they might otherwise be
   // cases. We need to keep these rooted because they might otherwise be
   // collected.
   // collected.
@@ -498,7 +499,7 @@ VALUE Message_descriptor(VALUE klass);
 VALUE Message_decode(VALUE klass, VALUE data);
 VALUE Message_decode(VALUE klass, VALUE data);
 VALUE Message_encode(VALUE klass, VALUE msg_rb);
 VALUE Message_encode(VALUE klass, VALUE msg_rb);
 VALUE Message_decode_json(VALUE klass, VALUE data);
 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);
 VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj);
 
 

File diff suppressed because it is too large
+ 416 - 175
ruby/ext/google/protobuf_c/upb.c


File diff suppressed because it is too large
+ 518 - 622
ruby/ext/google/protobuf_c/upb.h


+ 5 - 0
ruby/tests/basic.rb

@@ -1161,7 +1161,12 @@ module BasicTest
       return if RUBY_PLATFORM == "java"
       return if RUBY_PLATFORM == "java"
       m = MapMessage.new(:map_string_int32 => {"a" => 1})
       m = MapMessage.new(:map_string_int32 => {"a" => 1})
       expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
       expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
+      expected_preserve = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
       assert MapMessage.encode_json(m) == expected
       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))
       m2 = MapMessage.decode_json(MapMessage.encode_json(m))
       assert m == m2
       assert m == m2
     end
     end

Some files were not shown because too many files changed in this diff