aboutsummaryrefslogtreecommitdiff
path: root/java/src/main
diff options
context:
space:
mode:
authorkenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-12-18 02:11:36 +0000
committerkenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-12-18 02:11:36 +0000
commitfccb146e3fe437b0df1e9c50d4b8e1080ddb4bd9 (patch)
tree9f2d9fe0267d96a54e541377ffeada3d0bff0d1d /java/src/main
parentd5cf7b55a6a1f959d1646785f63ca2b62da78079 (diff)
downloadprotobuf-fccb146e3fe437b0df1e9c50d4b8e1080ddb4bd9.tar.gz
protobuf-fccb146e3fe437b0df1e9c50d4b8e1080ddb4bd9.tar.bz2
protobuf-fccb146e3fe437b0df1e9c50d4b8e1080ddb4bd9.zip
Massive roll-up of changes. See CHANGES.txt.
Diffstat (limited to 'java/src/main')
-rw-r--r--java/src/main/java/com/google/protobuf/AbstractMessage.java35
-rw-r--r--java/src/main/java/com/google/protobuf/AbstractMessageLite.java28
-rw-r--r--java/src/main/java/com/google/protobuf/ByteString.java18
-rw-r--r--java/src/main/java/com/google/protobuf/CodedInputStream.java27
-rw-r--r--java/src/main/java/com/google/protobuf/Descriptors.java118
-rw-r--r--java/src/main/java/com/google/protobuf/ExtensionRegistry.java5
-rw-r--r--java/src/main/java/com/google/protobuf/GeneratedMessage.java4
-rw-r--r--java/src/main/java/com/google/protobuf/GeneratedMessageLite.java31
-rw-r--r--java/src/main/java/com/google/protobuf/Message.java4
-rw-r--r--java/src/main/java/com/google/protobuf/MessageLite.java8
-rw-r--r--java/src/main/java/com/google/protobuf/TextFormat.java2
-rw-r--r--java/src/main/java/com/google/protobuf/UnknownFieldSet.java20
-rw-r--r--java/src/main/java/com/google/protobuf/WireFormat.java18
13 files changed, 212 insertions, 106 deletions
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java
index e5bdefe3..b059bc98 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -311,6 +311,12 @@ public abstract class AbstractMessage extends AbstractMessageLite
} else {
field = extension.descriptor;
defaultInstance = extension.defaultInstance;
+ if (defaultInstance == null &&
+ field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ throw new IllegalStateException(
+ "Message-typed extension lacked default instance: " +
+ field.getFullName());
+ }
}
} else {
field = null;
@@ -319,15 +325,28 @@ public abstract class AbstractMessage extends AbstractMessageLite
field = type.findFieldByNumber(fieldNumber);
}
- if (field == null || wireType !=
- FieldSet.getWireFormatForFieldType(
- field.getLiteType(),
- field.getOptions().getPacked())) {
- // Unknown field or wrong wire type. Skip.
+ boolean unknown = false;
+ boolean packed = false;
+ if (field == null) {
+ unknown = true; // Unknown field.
+ } else if (wireType == FieldSet.getWireFormatForFieldType(
+ field.getLiteType(),
+ false /* isPacked */)) {
+ packed = false;
+ } else if (field.isPackable() &&
+ wireType == FieldSet.getWireFormatForFieldType(
+ field.getLiteType(),
+ true /* isPacked */)) {
+ packed = true;
+ } else {
+ unknown = true; // Unknown wire type.
+ }
+
+ if (unknown) { // Unknown field or wrong wire type. Skip.
return unknownFields.mergeFieldFrom(tag, input);
}
- if (field.getOptions().getPacked()) {
+ if (packed) {
final int length = input.readRawVarint32();
final int limit = input.pushLimit(length);
if (field.getLiteType() == WireFormat.FieldType.ENUM) {
@@ -673,13 +692,13 @@ public abstract class AbstractMessage extends AbstractMessageLite
}
@Override
- public BuilderType mergeDelimitedFrom(final InputStream input)
+ public boolean mergeDelimitedFrom(final InputStream input)
throws IOException {
return super.mergeDelimitedFrom(input);
}
@Override
- public BuilderType mergeDelimitedFrom(
+ public boolean mergeDelimitedFrom(
final InputStream input,
final ExtensionRegistryLite extensionRegistry)
throws IOException {
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
index 86bf02d8..9210d853 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
+++ b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -86,7 +86,7 @@ public abstract class AbstractMessageLite implements MessageLite {
CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
final CodedOutputStream codedOutput =
CodedOutputStream.newInstance(output, bufferSize);
- codedOutput.writeRawVarint32(getSerializedSize());
+ codedOutput.writeRawVarint32(serialized);
writeTo(codedOutput);
codedOutput.flush();
}
@@ -105,13 +105,7 @@ public abstract class AbstractMessageLite implements MessageLite {
public BuilderType mergeFrom(final CodedInputStream input)
throws IOException {
- // TODO(kenton): Don't use null here. Currently we have to because
- // using ExtensionRegistry.getEmptyRegistry() would imply a dependency
- // on ExtensionRegistry. However, AbstractMessage overrides this with
- // a correct implementation, and lite messages don't yet support
- // extensions, so it ends up not mattering for now. It will matter
- // once lite messages support extensions.
- return mergeFrom(input, null);
+ return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
}
// Re-defined here for return type covariance.
@@ -275,20 +269,24 @@ public abstract class AbstractMessageLite implements MessageLite {
}
}
- public BuilderType mergeDelimitedFrom(
+ public boolean mergeDelimitedFrom(
final InputStream input,
final ExtensionRegistryLite extensionRegistry)
throws IOException {
- final int size = CodedInputStream.readRawVarint32(input);
+ final int firstByte = input.read();
+ if (firstByte == -1) {
+ return false;
+ }
+ final int size = CodedInputStream.readRawVarint32(firstByte, input);
final InputStream limitedInput = new LimitedInputStream(input, size);
- return mergeFrom(limitedInput, extensionRegistry);
+ mergeFrom(limitedInput, extensionRegistry);
+ return true;
}
- public BuilderType mergeDelimitedFrom(final InputStream input)
+ public boolean mergeDelimitedFrom(final InputStream input)
throws IOException {
- final int size = CodedInputStream.readRawVarint32(input);
- final InputStream limitedInput = new LimitedInputStream(input, size);
- return mergeFrom(limitedInput);
+ return mergeDelimitedFrom(input,
+ ExtensionRegistryLite.getEmptyRegistry());
}
/**
diff --git a/java/src/main/java/com/google/protobuf/ByteString.java b/java/src/main/java/com/google/protobuf/ByteString.java
index c83c335c..c043df8b 100644
--- a/java/src/main/java/com/google/protobuf/ByteString.java
+++ b/java/src/main/java/com/google/protobuf/ByteString.java
@@ -99,6 +99,24 @@ public final class ByteString {
}
/**
+ * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into
+ * a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final ByteBuffer bytes, final int size) {
+ final byte[] copy = new byte[size];
+ bytes.get(copy);
+ return new ByteString(copy);
+ }
+
+ /**
+ * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into
+ * a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final ByteBuffer bytes) {
+ return copyFrom(bytes, bytes.remaining());
+ }
+
+ /**
* Encodes {@code text} into a sequence of bytes using the named charset
* and returns the result as a {@code ByteString}.
*/
diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java
index f339c00e..f0c1051d 100644
--- a/java/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -84,8 +84,9 @@ public final class CodedInputStream {
}
lastTag = readRawVarint32();
- if (lastTag == 0) {
- // If we actually read zero, that's not a valid tag.
+ if (WireFormat.getTagFieldNumber(lastTag) == 0) {
+ // If we actually read zero (or any tag number corresponding to field
+ // number zero), that's not a valid tag.
throw InvalidProtocolBufferException.invalidTag();
}
return lastTag;
@@ -355,8 +356,26 @@ public final class CodedInputStream {
* CodedInputStream buffers its input.
*/
static int readRawVarint32(final InputStream input) throws IOException {
- int result = 0;
- int offset = 0;
+ final int firstByte = input.read();
+ if (firstByte == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ return readRawVarint32(firstByte, input);
+ }
+
+ /**
+ * Like {@link #readRawVarint32(InputStream)}, but expects that the caller
+ * has already read one byte. This allows the caller to determine if EOF
+ * has been reached before attempting to read.
+ */
+ static int readRawVarint32(final int firstByte,
+ final InputStream input) throws IOException {
+ if ((firstByte & 0x80) == 0) {
+ return firstByte;
+ }
+
+ int result = firstByte & 0x7f;
+ int offset = 7;
for (; offset < 32; offset += 7) {
final int b = input.read();
if (b == -1) {
diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/src/main/java/com/google/protobuf/Descriptors.java
index 0c162d5d..c5e9a04b 100644
--- a/java/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/src/main/java/com/google/protobuf/Descriptors.java
@@ -48,7 +48,7 @@ import java.io.UnsupportedEncodingException;
* (given a message object of the type) {@code message.getDescriptorForType()}.
*
* Descriptors are built from DescriptorProtos, as defined in
- * {@code net/proto2/proto/descriptor.proto}.
+ * {@code google/protobuf/descriptor.proto}.
*
* @author kenton@google.com Kenton Varda
*/
@@ -699,6 +699,11 @@ public final class Descriptors {
return getOptions().getPacked();
}
+ /** Can this field be packed? i.e. is it a repeated primitive field? */
+ public boolean isPackable() {
+ return isRepeated() && getLiteType().isPackable();
+ }
+
/** Returns true if the field had an explicitly-defined default value. */
public boolean hasDefaultValue() { return proto.hasDefaultValue(); }
@@ -810,39 +815,34 @@ public final class Descriptors {
private Object defaultValue;
public enum Type {
- DOUBLE (FieldDescriptorProto.Type.TYPE_DOUBLE , JavaType.DOUBLE ),
- FLOAT (FieldDescriptorProto.Type.TYPE_FLOAT , JavaType.FLOAT ),
- INT64 (FieldDescriptorProto.Type.TYPE_INT64 , JavaType.LONG ),
- UINT64 (FieldDescriptorProto.Type.TYPE_UINT64 , JavaType.LONG ),
- INT32 (FieldDescriptorProto.Type.TYPE_INT32 , JavaType.INT ),
- FIXED64 (FieldDescriptorProto.Type.TYPE_FIXED64 , JavaType.LONG ),
- FIXED32 (FieldDescriptorProto.Type.TYPE_FIXED32 , JavaType.INT ),
- BOOL (FieldDescriptorProto.Type.TYPE_BOOL , JavaType.BOOLEAN ),
- STRING (FieldDescriptorProto.Type.TYPE_STRING , JavaType.STRING ),
- GROUP (FieldDescriptorProto.Type.TYPE_GROUP , JavaType.MESSAGE ),
- MESSAGE (FieldDescriptorProto.Type.TYPE_MESSAGE , JavaType.MESSAGE ),
- BYTES (FieldDescriptorProto.Type.TYPE_BYTES , JavaType.BYTE_STRING),
- UINT32 (FieldDescriptorProto.Type.TYPE_UINT32 , JavaType.INT ),
- ENUM (FieldDescriptorProto.Type.TYPE_ENUM , JavaType.ENUM ),
- SFIXED32(FieldDescriptorProto.Type.TYPE_SFIXED32, JavaType.INT ),
- SFIXED64(FieldDescriptorProto.Type.TYPE_SFIXED64, JavaType.LONG ),
- SINT32 (FieldDescriptorProto.Type.TYPE_SINT32 , JavaType.INT ),
- SINT64 (FieldDescriptorProto.Type.TYPE_SINT64 , JavaType.LONG );
-
- Type(final FieldDescriptorProto.Type proto, final JavaType javaType) {
- this.proto = proto;
+ DOUBLE (JavaType.DOUBLE ),
+ FLOAT (JavaType.FLOAT ),
+ INT64 (JavaType.LONG ),
+ UINT64 (JavaType.LONG ),
+ INT32 (JavaType.INT ),
+ FIXED64 (JavaType.LONG ),
+ FIXED32 (JavaType.INT ),
+ BOOL (JavaType.BOOLEAN ),
+ STRING (JavaType.STRING ),
+ GROUP (JavaType.MESSAGE ),
+ MESSAGE (JavaType.MESSAGE ),
+ BYTES (JavaType.BYTE_STRING),
+ UINT32 (JavaType.INT ),
+ ENUM (JavaType.ENUM ),
+ SFIXED32(JavaType.INT ),
+ SFIXED64(JavaType.LONG ),
+ SINT32 (JavaType.INT ),
+ SINT64 (JavaType.LONG );
+
+ Type(final JavaType javaType) {
this.javaType = javaType;
-
- if (ordinal() != proto.getNumber() - 1) {
- throw new RuntimeException(
- "descriptor.proto changed but Desrciptors.java wasn't updated.");
- }
}
- private FieldDescriptorProto.Type proto;
private JavaType javaType;
- public FieldDescriptorProto.Type toProto() { return proto; }
+ public FieldDescriptorProto.Type toProto() {
+ return FieldDescriptorProto.Type.valueOf(ordinal() + 1);
+ }
public JavaType getJavaType() { return javaType; }
public static Type valueOf(final FieldDescriptorProto.Type type) {
@@ -902,16 +902,10 @@ public final class Descriptors {
}
// Only repeated primitive fields may be packed.
- if (proto.getOptions().getPacked()) {
- if (proto.getLabel() != FieldDescriptorProto.Label.LABEL_REPEATED ||
- proto.getType() == FieldDescriptorProto.Type.TYPE_STRING ||
- proto.getType() == FieldDescriptorProto.Type.TYPE_GROUP ||
- proto.getType() == FieldDescriptorProto.Type.TYPE_MESSAGE ||
- proto.getType() == FieldDescriptorProto.Type.TYPE_BYTES) {
- throw new DescriptorValidationException(this,
- "[packed = true] can only be specified for repeated primitive " +
- "fields.");
- }
+ if (proto.getOptions().getPacked() && !isPackable()) {
+ throw new DescriptorValidationException(this,
+ "[packed = true] can only be specified for repeated primitive " +
+ "fields.");
}
if (isExtension) {
@@ -1030,10 +1024,26 @@ public final class Descriptors {
defaultValue = TextFormat.parseUInt64(proto.getDefaultValue());
break;
case FLOAT:
- defaultValue = Float.valueOf(proto.getDefaultValue());
+ if (proto.getDefaultValue().equals("inf")) {
+ defaultValue = Float.POSITIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("-inf")) {
+ defaultValue = Float.NEGATIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("nan")) {
+ defaultValue = Float.NaN;
+ } else {
+ defaultValue = Float.valueOf(proto.getDefaultValue());
+ }
break;
case DOUBLE:
- defaultValue = Double.valueOf(proto.getDefaultValue());
+ if (proto.getDefaultValue().equals("inf")) {
+ defaultValue = Double.POSITIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("-inf")) {
+ defaultValue = Double.NEGATIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("nan")) {
+ defaultValue = Double.NaN;
+ } else {
+ defaultValue = Double.valueOf(proto.getDefaultValue());
+ }
break;
case BOOL:
defaultValue = Boolean.valueOf(proto.getDefaultValue());
@@ -1064,12 +1074,9 @@ public final class Descriptors {
"Message type had default value.");
}
} catch (NumberFormatException e) {
- final DescriptorValidationException validationException =
- new DescriptorValidationException(this,
- "Could not parse default value: \"" +
- proto.getDefaultValue() + '\"');
- validationException.initCause(e);
- throw validationException;
+ throw new DescriptorValidationException(this,
+ "Could not parse default value: \"" +
+ proto.getDefaultValue() + '\"', e);
}
} else {
// Determine the default default for this field.
@@ -1536,14 +1543,7 @@ public final class Descriptors {
private DescriptorValidationException(
final GenericDescriptor problemDescriptor,
final String description) {
- this(problemDescriptor, description, null);
- }
-
- private DescriptorValidationException(
- final GenericDescriptor problemDescriptor,
- final String description,
- final Throwable cause) {
- super(problemDescriptor.getFullName() + ": " + description, cause);
+ super(problemDescriptor.getFullName() + ": " + description);
// Note that problemDescriptor may be partially uninitialized, so we
// don't want to expose it directly to the user. So, we only provide
@@ -1554,6 +1554,14 @@ public final class Descriptors {
}
private DescriptorValidationException(
+ final GenericDescriptor problemDescriptor,
+ final String description,
+ final Throwable cause) {
+ this(problemDescriptor, description);
+ initCause(cause);
+ }
+
+ private DescriptorValidationException(
final FileDescriptor problemDescriptor,
final String description) {
super(problemDescriptor.getName() + ": " + description);
diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
index 87bbd6eb..d4f6ba9e 100644
--- a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
+++ b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
@@ -157,6 +157,11 @@ public final class ExtensionRegistry extends ExtensionRegistryLite {
public void add(final GeneratedMessage.GeneratedExtension<?, ?> extension) {
if (extension.getDescriptor().getJavaType() ==
FieldDescriptor.JavaType.MESSAGE) {
+ if (extension.getMessageDefaultInstance() == null) {
+ throw new IllegalStateException(
+ "Registered message-type extension had null default instance: " +
+ extension.getDescriptor().getFullName());
+ }
add(new ExtensionInfo(extension.getDescriptor(),
extension.getMessageDefaultInstance()));
} else {
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
index 4994faad..b5583ba3 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -789,6 +789,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
messageDefaultInstance =
(Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"),
null);
+ if (messageDefaultInstance == null) {
+ throw new IllegalStateException(
+ type.getName() + ".getDefaultInstance() returned null.");
+ }
break;
case ENUM:
enumValueOf = getMethodOrDie(type, "valueOf",
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index c68414bd..e327f745 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -303,7 +303,7 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
final ExtensionRegistryLite extensionRegistry,
final int tag) throws IOException {
final FieldSet<ExtensionDescriptor> extensions =
- internalGetResult().extensions;
+ ((ExtendableMessage) internalGetResult()).extensions;
final int wireType = WireFormat.getTagWireType(tag);
final int fieldNumber = WireFormat.getTagFieldNumber(tag);
@@ -312,15 +312,29 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
extensionRegistry.findLiteExtensionByNumber(
getDefaultInstanceForType(), fieldNumber);
- if (extension == null || wireType !=
- FieldSet.getWireFormatForFieldType(
- extension.descriptor.getLiteType(),
- extension.descriptor.isPacked())) {
- // Unknown field or wrong wire type. Skip.
+ boolean unknown = false;
+ boolean packed = false;
+ if (extension == null) {
+ unknown = true; // Unknown field.
+ } else if (wireType == FieldSet.getWireFormatForFieldType(
+ extension.descriptor.getLiteType(),
+ false /* isPacked */)) {
+ packed = false; // Normal, unpacked value.
+ } else if (extension.descriptor.isRepeated &&
+ extension.descriptor.type.isPackable() &&
+ wireType == FieldSet.getWireFormatForFieldType(
+ extension.descriptor.getLiteType(),
+ true /* isPacked */)) {
+ packed = true; // Packed value.
+ } else {
+ unknown = true; // Wrong wire type.
+ }
+
+ if (unknown) { // Unknown field or wrong wire type. Skip.
return input.skipField(tag);
}
- if (extension.descriptor.isPacked()) {
+ if (packed) {
final int length = input.readRawVarint32();
final int limit = input.pushLimit(length);
if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
@@ -396,7 +410,8 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
}
protected final void mergeExtensionFields(final MessageType other) {
- internalGetResult().extensions.mergeFrom(other.extensions);
+ ((ExtendableMessage) internalGetResult()).extensions.mergeFrom(
+ ((ExtendableMessage) other).extensions);
}
}
diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/src/main/java/com/google/protobuf/Message.java
index c11abdc5..8c29e212 100644
--- a/java/src/main/java/com/google/protobuf/Message.java
+++ b/java/src/main/java/com/google/protobuf/Message.java
@@ -296,9 +296,9 @@ public interface Message extends MessageLite {
Builder mergeFrom(InputStream input,
ExtensionRegistryLite extensionRegistry)
throws IOException;
- Builder mergeDelimitedFrom(InputStream input)
+ boolean mergeDelimitedFrom(InputStream input)
throws IOException;
- Builder mergeDelimitedFrom(InputStream input,
+ boolean mergeDelimitedFrom(InputStream input,
ExtensionRegistryLite extensionRegistry)
throws IOException;
}
diff --git a/java/src/main/java/com/google/protobuf/MessageLite.java b/java/src/main/java/com/google/protobuf/MessageLite.java
index 3ebe9bba..cf7f39e2 100644
--- a/java/src/main/java/com/google/protobuf/MessageLite.java
+++ b/java/src/main/java/com/google/protobuf/MessageLite.java
@@ -317,14 +317,18 @@ public interface MessageLite {
* then the message data. Use
* {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in
* this format.
+ *
+ * @returns True if successful, or false if the stream is at EOF when the
+ * method starts. Any other error (including reaching EOF during
+ * parsing) will cause an exception to be thrown.
*/
- Builder mergeDelimitedFrom(InputStream input)
+ boolean mergeDelimitedFrom(InputStream input)
throws IOException;
/**
* Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions.
*/
- Builder mergeDelimitedFrom(InputStream input,
+ boolean mergeDelimitedFrom(InputStream input,
ExtensionRegistryLite extensionRegistry)
throws IOException;
}
diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/src/main/java/com/google/protobuf/TextFormat.java
index a855720b..698992f0 100644
--- a/java/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/src/main/java/com/google/protobuf/TextFormat.java
@@ -426,7 +426,7 @@ public final class TextFormat {
Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE);
private static final Pattern TOKEN = Pattern.compile(
"[a-zA-Z_][0-9a-zA-Z_+-]*+|" + // an identifier
- "[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number
+ "[.]?[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number
"\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" + // a double-quoted string
"\'([^\"\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string
Pattern.MULTILINE);
diff --git a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
index 7f7e4939..26a15d00 100644
--- a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
+++ b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -30,6 +30,8 @@
package com.google.protobuf;
+import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -551,19 +553,23 @@ public final class UnknownFieldSet implements MessageLite {
return this;
}
- public Builder mergeDelimitedFrom(InputStream input)
+ public boolean mergeDelimitedFrom(InputStream input)
throws IOException {
- final int size = CodedInputStream.readRawVarint32(input);
- final InputStream limitedInput =
- new AbstractMessage.Builder.LimitedInputStream(input, size);
- return mergeFrom(limitedInput, null);
+ final int firstByte = input.read();
+ if (firstByte == -1) {
+ return false;
+ }
+ final int size = CodedInputStream.readRawVarint32(firstByte, input);
+ final InputStream limitedInput = new LimitedInputStream(input, size);
+ mergeFrom(limitedInput);
+ return true;
}
- public Builder mergeDelimitedFrom(
+ public boolean mergeDelimitedFrom(
InputStream input,
ExtensionRegistryLite extensionRegistry) throws IOException {
// UnknownFieldSet has no extensions.
- return mergeFrom(input);
+ return mergeDelimitedFrom(input);
}
public Builder mergeFrom(
diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/src/main/java/com/google/protobuf/WireFormat.java
index 3b0bdcd0..c46f7b0a 100644
--- a/java/src/main/java/com/google/protobuf/WireFormat.java
+++ b/java/src/main/java/com/google/protobuf/WireFormat.java
@@ -113,10 +113,18 @@ public final class WireFormat {
FIXED64 (JavaType.LONG , WIRETYPE_FIXED64 ),
FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ),
BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ),
- STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED),
- GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ),
- MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED),
- BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED),
+ STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) {
+ public boolean isPackable() { return false; }
+ },
+ GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) {
+ public boolean isPackable() { return false; }
+ },
+ MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) {
+ public boolean isPackable() { return false; }
+ },
+ BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
+ public boolean isPackable() { return false; }
+ },
UINT32 (JavaType.INT , WIRETYPE_VARINT ),
ENUM (JavaType.ENUM , WIRETYPE_VARINT ),
SFIXED32(JavaType.INT , WIRETYPE_FIXED32 ),
@@ -134,6 +142,8 @@ public final class WireFormat {
public JavaType getJavaType() { return javaType; }
public int getWireType() { return wireType; }
+
+ public boolean isPackable() { return true; }
}
// Field numbers for feilds in MessageSet wire format.