From b7cf53ba3b46eb17180465d3d3bb151fa4d93f3d Mon Sep 17 00:00:00 2001 From: Brian Duff Date: Fri, 3 Oct 2014 14:41:43 -0700 Subject: Fix bug with large extension field numbers. Previously, extensions with field numbers greater than 268435455 would result in a compile time error in generated code that looks something like this: Foo.java:3178: error: integer number too large: 3346754610 3346754610); This is because we were trying to represent the tag number (an unsigned int) using a java int constant, but java int constants are signed, and can't exceed Integer.MAX_VALUE. Fixed by declaring it as a long instead, and casting it down to an int in the implementation. This is safe, because the tag value always fits in 32 bis. Change-Id: If2017bacb4e20af667eaeaf9b65ddc2c30a7709f --- .../java/com/google/protobuf/nano/Extension.java | 22 ++++++++++++++-------- .../compiler/javanano/javanano_extension.cc | 2 +- src/google/protobuf/unittest_extension_nano.proto | 3 +++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/java/src/main/java/com/google/protobuf/nano/Extension.java b/java/src/main/java/com/google/protobuf/nano/Extension.java index a851daf..728f0dc 100644 --- a/java/src/main/java/com/google/protobuf/nano/Extension.java +++ b/java/src/main/java/com/google/protobuf/nano/Extension.java @@ -74,6 +74,11 @@ public class Extension, T> { public static final int TYPE_SINT32 = 17; public static final int TYPE_SINT64 = 18; + // Note: these create...() methods take a long for the tag parameter, + // because tags are represented as unsigned longs, and these values exist + // in generated code as long values. However, they can fit in 32-bits, so + // it's safe to cast them to int without loss of precision. + /** * Creates an {@code Extension} of the given message type and tag number. * Should be used by the generated code only. @@ -81,8 +86,8 @@ public class Extension, T> { * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP} */ public static , T extends MessageNano> - Extension createMessageTyped(int type, Class clazz, int tag) { - return new Extension(type, clazz, tag, false); + Extension createMessageTyped(int type, Class clazz, long tag) { + return new Extension(type, clazz, (int) tag, false); } /** @@ -92,8 +97,8 @@ public class Extension, T> { * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP} */ public static , T extends MessageNano> - Extension createRepeatedMessageTyped(int type, Class clazz, int tag) { - return new Extension(type, clazz, tag, true); + Extension createRepeatedMessageTyped(int type, Class clazz, long tag) { + return new Extension(type, clazz, (int) tag, true); } /** @@ -104,8 +109,8 @@ public class Extension, T> { * @param clazz the boxed Java type of this extension */ public static , T> - Extension createPrimitiveTyped(int type, Class clazz, int tag) { - return new PrimitiveExtension(type, clazz, tag, false, 0, 0); + Extension createPrimitiveTyped(int type, Class clazz, long tag) { + return new PrimitiveExtension(type, clazz, (int) tag, false, 0, 0); } /** @@ -117,8 +122,9 @@ public class Extension, T> { */ public static , T> Extension createRepeatedPrimitiveTyped( - int type, Class clazz, int tag, int nonPackedTag, int packedTag) { - return new PrimitiveExtension(type, clazz, tag, true, nonPackedTag, packedTag); + int type, Class clazz, long tag, long nonPackedTag, long packedTag) { + return new PrimitiveExtension(type, clazz, (int) tag, true, + (int) nonPackedTag, (int) packedTag); } /** diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.cc b/src/google/protobuf/compiler/javanano/javanano_extension.cc index 754ed55..0b9d1d8 100644 --- a/src/google/protobuf/compiler/javanano/javanano_extension.cc +++ b/src/google/protobuf/compiler/javanano/javanano_extension.cc @@ -140,7 +140,7 @@ void ExtensionGenerator::Generate(io::Printer* printer) const { " com.google.protobuf.nano.Extension.create$repeated$$ext_type$(\n" " com.google.protobuf.nano.Extension.$type$,\n" " $class$.class,\n" - " $tag_params$);\n"); + " $tag_params$L);\n"); } } // namespace javanano diff --git a/src/google/protobuf/unittest_extension_nano.proto b/src/google/protobuf/unittest_extension_nano.proto index 2a678a8..d1c5766 100644 --- a/src/google/protobuf/unittest_extension_nano.proto +++ b/src/google/protobuf/unittest_extension_nano.proto @@ -21,6 +21,9 @@ message AnotherMessage { message ContainerMessage { extend ExtendableMessage { optional bool another_thing = 100; + // The largest permitted field number, per + // https://developers.google.com/protocol-buffers/docs/proto#simple + optional bool large_field_number = 536870911; } } -- cgit v1.1