From 7b1d6abbe452c64958de7ef52ce596cf3640b7db Mon Sep 17 00:00:00 2001 From: Rob Widmer Date: Wed, 16 Sep 2020 10:59:05 -0400 Subject: [PATCH] Fix some more failing tests --- .../jruby/RubyEnumBuilderContext.java | 1 + .../protobuf/jruby/RubyEnumDescriptor.java | 8 ++++++- .../google/protobuf/jruby/RubyMessage.java | 22 ++++++++++++++++--- ruby/tests/gc_test.rb | 12 +++++++--- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java index 5984470aae..38d31ad7fe 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java @@ -66,6 +66,7 @@ public class RubyEnumBuilderContext extends RubyObject { this.fileBuilderContext = (RubyFileBuilderContext) fileBuilderContext; this.builder = this.fileBuilderContext.getNewEnumBuilder(); this.builder.setName(name.asJavaString()); + this.builder.getOptionsBuilder().setAllowAlias(true); return this; } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java index 3a1ce0bf16..e9c1f10abe 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java @@ -152,7 +152,13 @@ public class RubyEnumDescriptor extends RubyObject { RubyModule enumModule = RubyModule.newModule(runtime); for (EnumValueDescriptor value : descriptor.getValues()) { - enumModule.defineConstant(value.getName(), runtime.newFixnum(value.getNumber())); + String name = value.getName(); + // Make sure its a valid constant name before trying to create it + if (Character.isUpperCase(name.codePointAt(0))) { + enumModule.defineConstant(name, runtime.newFixnum(value.getNumber())); + } else { + runtime.getWarnings().warn("Enum value " + name + " does not start with an uppercase letter as is required for Ruby constants."); + } } enumModule.instance_variable_set(runtime.newString(Utils.DESCRIPTOR_INSTANCE_VAR), this); diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java index 110c567869..a905c9a260 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -291,9 +291,25 @@ public class RubyMessage extends RubyObject { if (!oneofDescriptor.isNil()) { RubyOneofDescriptor rubyOneofDescriptor = (RubyOneofDescriptor) oneofDescriptor; - FieldDescriptor fieldDescriptor = oneofCases.get(rubyOneofDescriptor.getDescriptor()); + OneofDescriptor ood = rubyOneofDescriptor.getDescriptor(); - return fieldDescriptor == null ? context.nil : runtime.newSymbol(fieldDescriptor.getName()); + // Check to see if we set this through ruby + FieldDescriptor fieldDescriptor = oneofCases.get(ood); + + if (fieldDescriptor == null) { + // See if we set this from decoding a message + fieldDescriptor = builder.getOneofFieldDescriptor(ood); + + if (fieldDescriptor == null) { + return context.nil; + } else { + // Cache it so we don't need to do multiple checks next time + oneofCases.put(ood, fieldDescriptor); + return runtime.newSymbol(fieldDescriptor.getName()); + } + } else { + return runtime.newSymbol(fieldDescriptor.getName()); + } } // If we find a field return its value @@ -468,7 +484,7 @@ public class RubyMessage extends RubyObject { try { ret.builder.mergeFrom(bin); } catch (InvalidProtocolBufferException e) { - throw context.runtime.newRuntimeError(e.getMessage()); + throw RaiseException.from(context.runtime, (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::ParseError"), e.getMessage()); } if (!ret.proto3) { diff --git a/ruby/tests/gc_test.rb b/ruby/tests/gc_test.rb index 6ef4e2e301..d7fecaeea1 100755 --- a/ruby/tests/gc_test.rb +++ b/ruby/tests/gc_test.rb @@ -95,9 +95,15 @@ class GCTest < Test::Unit::TestCase data = A::B::C::TestMessage.encode(from) to = A::B::C::TestMessage.decode(data) - from = get_msg_proto2 - data = A::B::Proto2::TestMessage.encode(from) - to = A::B::Proto2::TestMessage.decode(data) + # This doesn't work for proto2 on JRuby because there is a nested required message. + # A::B::Proto2::TestMessage has :required_msg which is of type: + # A::B::Proto2::TestMessage so there is no way to generate a valid + # message that doesn't exceed the depth limit + if !defined? JRUBY_VERSION + from = get_msg_proto2 + data = A::B::Proto2::TestMessage.encode(from) + to = A::B::Proto2::TestMessage.decode(data) + end GC.stress = old_gc puts "passed" end