parent
c5553a3d18
commit
4de8f55113
236 changed files with 27852 additions and 7557 deletions
@ -0,0 +1,96 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
/** |
||||
* Interface that generated extensions implement. |
||||
* |
||||
* @author liujisi@google.com (Jisi Liu) |
||||
*/ |
||||
public abstract class Extension<ContainingType extends MessageLite, Type> { |
||||
/** Returns the field number of the extension. */ |
||||
public abstract int getNumber(); |
||||
|
||||
/** Returns the type of the field. */ |
||||
public abstract WireFormat.FieldType getLiteType(); |
||||
|
||||
/** Returns whether it is a repeated field. */ |
||||
public abstract boolean isRepeated(); |
||||
|
||||
/** Returns the descriptor of the extension. */ |
||||
public abstract Descriptors.FieldDescriptor getDescriptor(); |
||||
|
||||
/** Returns the default value of the extension field. */ |
||||
public abstract Type getDefaultValue(); |
||||
|
||||
/** |
||||
* Returns the default instance of the extension field, if it's a message |
||||
* extension. |
||||
*/ |
||||
public abstract MessageLite getMessageDefaultInstance(); |
||||
|
||||
// All the methods below are extension implementation details.
|
||||
|
||||
/** |
||||
* The API type that the extension is used for. |
||||
*/ |
||||
protected enum ExtensionType { |
||||
IMMUTABLE, |
||||
MUTABLE, |
||||
PROTO1, |
||||
} |
||||
|
||||
protected ExtensionType getExtensionType() { |
||||
// TODO(liujisi): make this abstract after we fix proto1.
|
||||
return ExtensionType.IMMUTABLE; |
||||
} |
||||
|
||||
/** |
||||
* Type of a message extension. |
||||
*/ |
||||
public enum MessageType { |
||||
PROTO1, |
||||
PROTO2, |
||||
} |
||||
|
||||
/** |
||||
* If the extension is a message extension (i.e., getLiteType() == MESSAGE), |
||||
* returns the type of the message, otherwise undefined. |
||||
*/ |
||||
public MessageType getMessageType() { |
||||
return MessageType.PROTO2; |
||||
} |
||||
|
||||
protected abstract Object fromReflectionType(Object value); |
||||
protected abstract Object singularFromReflectionType(Object value); |
||||
protected abstract Object toReflectionType(Object value); |
||||
protected abstract Object singularToReflectionType(Object value); |
||||
} |
@ -0,0 +1,931 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.TreeMap; |
||||
|
||||
/** |
||||
* Reflection utility methods shared by both mutable and immutable messages. |
||||
* |
||||
* @author liujisi@google.com (Pherl Liu) |
||||
*/ |
||||
class MessageReflection { |
||||
|
||||
static void writeMessageTo(Message message, CodedOutputStream output, |
||||
boolean alwaysWriteRequiredFields) |
||||
throws IOException { |
||||
final boolean isMessageSet = |
||||
message.getDescriptorForType().getOptions().getMessageSetWireFormat(); |
||||
|
||||
Map<FieldDescriptor, Object> fields = message.getAllFields(); |
||||
if (alwaysWriteRequiredFields) { |
||||
fields = new TreeMap<FieldDescriptor, Object>(fields); |
||||
for (final FieldDescriptor field : |
||||
message.getDescriptorForType().getFields()) { |
||||
if (field.isRequired() && !fields.containsKey(field)) { |
||||
fields.put(field, message.getField(field)); |
||||
} |
||||
} |
||||
} |
||||
for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
||||
fields.entrySet()) { |
||||
final Descriptors.FieldDescriptor field = entry.getKey(); |
||||
final Object value = entry.getValue(); |
||||
if (isMessageSet && field.isExtension() && |
||||
field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && |
||||
!field.isRepeated()) { |
||||
output.writeMessageSetExtension(field.getNumber(), (Message) value); |
||||
} else { |
||||
FieldSet.writeField(field, value, output); |
||||
} |
||||
} |
||||
|
||||
final UnknownFieldSet unknownFields = message.getUnknownFields(); |
||||
if (isMessageSet) { |
||||
unknownFields.writeAsMessageSetTo(output); |
||||
} else { |
||||
unknownFields.writeTo(output); |
||||
} |
||||
} |
||||
|
||||
static int getSerializedSize(Message message) { |
||||
int size = 0; |
||||
final boolean isMessageSet = |
||||
message.getDescriptorForType().getOptions().getMessageSetWireFormat(); |
||||
|
||||
for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
||||
message.getAllFields().entrySet()) { |
||||
final Descriptors.FieldDescriptor field = entry.getKey(); |
||||
final Object value = entry.getValue(); |
||||
if (isMessageSet && field.isExtension() && |
||||
field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && |
||||
!field.isRepeated()) { |
||||
size += CodedOutputStream.computeMessageSetExtensionSize( |
||||
field.getNumber(), (Message) value); |
||||
} else { |
||||
size += FieldSet.computeFieldSize(field, value); |
||||
} |
||||
} |
||||
|
||||
final UnknownFieldSet unknownFields = message.getUnknownFields(); |
||||
if (isMessageSet) { |
||||
size += unknownFields.getSerializedSizeAsMessageSet(); |
||||
} else { |
||||
size += unknownFields.getSerializedSize(); |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
static String delimitWithCommas(List<String> parts) { |
||||
StringBuilder result = new StringBuilder(); |
||||
for (String part : parts) { |
||||
if (result.length() > 0) { |
||||
result.append(", "); |
||||
} |
||||
result.append(part); |
||||
} |
||||
return result.toString(); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
static boolean isInitialized(MessageOrBuilder message) { |
||||
// Check that all required fields are present.
|
||||
for (final Descriptors.FieldDescriptor field : message |
||||
.getDescriptorForType() |
||||
.getFields()) { |
||||
if (field.isRequired()) { |
||||
if (!message.hasField(field)) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Check that embedded messages are initialized.
|
||||
for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
||||
message.getAllFields().entrySet()) { |
||||
final Descriptors.FieldDescriptor field = entry.getKey(); |
||||
if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { |
||||
if (field.isRepeated()) { |
||||
for (final Message element |
||||
: (List<Message>) entry.getValue()) { |
||||
if (!element.isInitialized()) { |
||||
return false; |
||||
} |
||||
} |
||||
} else { |
||||
if (!((Message) entry.getValue()).isInitialized()) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static String subMessagePrefix(final String prefix, |
||||
final Descriptors.FieldDescriptor field, |
||||
final int index) { |
||||
final StringBuilder result = new StringBuilder(prefix); |
||||
if (field.isExtension()) { |
||||
result.append('(') |
||||
.append(field.getFullName()) |
||||
.append(')'); |
||||
} else { |
||||
result.append(field.getName()); |
||||
} |
||||
if (index != -1) { |
||||
result.append('[') |
||||
.append(index) |
||||
.append(']'); |
||||
} |
||||
result.append('.'); |
||||
return result.toString(); |
||||
} |
||||
|
||||
private static void findMissingFields(final MessageOrBuilder message, |
||||
final String prefix, |
||||
final List<String> results) { |
||||
for (final Descriptors.FieldDescriptor field : |
||||
message.getDescriptorForType().getFields()) { |
||||
if (field.isRequired() && !message.hasField(field)) { |
||||
results.add(prefix + field.getName()); |
||||
} |
||||
} |
||||
|
||||
for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
||||
message.getAllFields().entrySet()) { |
||||
final Descriptors.FieldDescriptor field = entry.getKey(); |
||||
final Object value = entry.getValue(); |
||||
|
||||
if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { |
||||
if (field.isRepeated()) { |
||||
int i = 0; |
||||
for (final Object element : (List) value) { |
||||
findMissingFields((MessageOrBuilder) element, |
||||
subMessagePrefix(prefix, field, i++), |
||||
results); |
||||
} |
||||
} else { |
||||
if (message.hasField(field)) { |
||||
findMissingFields((MessageOrBuilder) value, |
||||
subMessagePrefix(prefix, field, -1), |
||||
results); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Populates {@code this.missingFields} with the full "path" of each missing |
||||
* required field in the given message. |
||||
*/ |
||||
static List<String> findMissingFields( |
||||
final MessageOrBuilder message) { |
||||
final List<String> results = new ArrayList<String>(); |
||||
findMissingFields(message, "", results); |
||||
return results; |
||||
} |
||||
|
||||
static interface MergeTarget { |
||||
enum ContainerType { |
||||
MESSAGE, EXTENSION_SET |
||||
} |
||||
|
||||
/** |
||||
* Returns the descriptor for the target. |
||||
*/ |
||||
public Descriptors.Descriptor getDescriptorForType(); |
||||
|
||||
public ContainerType getContainerType(); |
||||
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByName( |
||||
ExtensionRegistry registry, String name); |
||||
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByNumber( |
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType, |
||||
int fieldNumber); |
||||
|
||||
/** |
||||
* Obtains the value of the given field, or the default value if it is not |
||||
* set. For primitive fields, the boxed primitive value is returned. For |
||||
* enum fields, the EnumValueDescriptor for the value is returned. For |
||||
* embedded message fields, the sub-message is returned. For repeated |
||||
* fields, a java.util.List is returned. |
||||
*/ |
||||
public Object getField(Descriptors.FieldDescriptor field); |
||||
|
||||
/** |
||||
* Returns true if the given field is set. This is exactly equivalent to |
||||
* calling the generated "has" accessor method corresponding to the field. |
||||
* |
||||
* @throws IllegalArgumentException The field is a repeated field, or {@code |
||||
* field.getContainingType() != getDescriptorForType()}. |
||||
*/ |
||||
boolean hasField(Descriptors.FieldDescriptor field); |
||||
|
||||
/** |
||||
* Sets a field to the given value. The value must be of the correct type |
||||
* for this field, i.e. the same type that |
||||
* {@link Message#getField(Descriptors.FieldDescriptor)} |
||||
* would return. |
||||
*/ |
||||
MergeTarget setField(Descriptors.FieldDescriptor field, Object value); |
||||
|
||||
/** |
||||
* Clears the field. This is exactly equivalent to calling the generated |
||||
* "clear" accessor method corresponding to the field. |
||||
*/ |
||||
MergeTarget clearField(Descriptors.FieldDescriptor field); |
||||
|
||||
/** |
||||
* Sets an element of a repeated field to the given value. The value must |
||||
* be of the correct type for this field, i.e. the same type that {@link |
||||
* Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return. |
||||
* |
||||
* @throws IllegalArgumentException The field is not a repeated field, or |
||||
* {@code field.getContainingType() != |
||||
* getDescriptorForType()}. |
||||
*/ |
||||
MergeTarget setRepeatedField(Descriptors.FieldDescriptor field, |
||||
int index, Object value); |
||||
|
||||
/** |
||||
* Like {@code setRepeatedField}, but appends the value as a new element. |
||||
* |
||||
* @throws IllegalArgumentException The field is not a repeated field, or |
||||
* {@code field.getContainingType() != |
||||
* getDescriptorForType()}. |
||||
*/ |
||||
MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, |
||||
Object value); |
||||
|
||||
/** |
||||
* Returns true if the given oneof is set. |
||||
* |
||||
* @throws IllegalArgumentException if |
||||
* {@code oneof.getContainingType() != getDescriptorForType()}. |
||||
*/ |
||||
boolean hasOneof(Descriptors.OneofDescriptor oneof); |
||||
|
||||
/** |
||||
* Clears the oneof. This is exactly equivalent to calling the generated |
||||
* "clear" accessor method corresponding to the oneof. |
||||
*/ |
||||
MergeTarget clearOneof(Descriptors.OneofDescriptor oneof); |
||||
|
||||
/** |
||||
* Obtains the FieldDescriptor if the given oneof is set. Returns null |
||||
* if no field is set. |
||||
*/ |
||||
Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof); |
||||
|
||||
/** |
||||
* Parse the input stream into a sub field group defined based on either |
||||
* FieldDescriptor or the default instance. |
||||
*/ |
||||
Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry, |
||||
Descriptors.FieldDescriptor descriptor, Message defaultInstance) |
||||
throws IOException; |
||||
|
||||
/** |
||||
* Parse the input stream into a sub field message defined based on either |
||||
* FieldDescriptor or the default instance. |
||||
*/ |
||||
Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry, |
||||
Descriptors.FieldDescriptor descriptor, Message defaultInstance) |
||||
throws IOException; |
||||
|
||||
/** |
||||
* Parse from a ByteString into a sub field message defined based on either |
||||
* FieldDescriptor or the default instance. There isn't a varint indicating |
||||
* the length of the message at the beginning of the input ByteString. |
||||
*/ |
||||
Object parseMessageFromBytes( |
||||
ByteString bytes, ExtensionRegistryLite registry, |
||||
Descriptors.FieldDescriptor descriptor, Message defaultInstance) |
||||
throws IOException; |
||||
|
||||
/** |
||||
* Read a primitive field from input. Note that builders and mutable |
||||
* messages may use different Java types to represent a primtive field. |
||||
*/ |
||||
Object readPrimitiveField( |
||||
CodedInputStream input, WireFormat.FieldType type, |
||||
boolean checkUtf8) throws IOException; |
||||
|
||||
/** |
||||
* Returns a new merge target for a sub-field. When defaultInstance is |
||||
* provided, it indicates the descriptor is for an extension type, and |
||||
* implementations should create a new instance from the defaultInstance |
||||
* prototype directly. |
||||
*/ |
||||
MergeTarget newMergeTargetForField( |
||||
Descriptors.FieldDescriptor descriptor, |
||||
Message defaultInstance); |
||||
|
||||
/** |
||||
* Finishes the merge and returns the underlying object. |
||||
*/ |
||||
Object finish(); |
||||
} |
||||
|
||||
static class BuilderAdapter implements MergeTarget { |
||||
|
||||
private final Message.Builder builder; |
||||
|
||||
public Descriptors.Descriptor getDescriptorForType() { |
||||
return builder.getDescriptorForType(); |
||||
} |
||||
|
||||
public BuilderAdapter(Message.Builder builder) { |
||||
this.builder = builder; |
||||
} |
||||
|
||||
public Object getField(Descriptors.FieldDescriptor field) { |
||||
return builder.getField(field); |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasField(Descriptors.FieldDescriptor field) { |
||||
return builder.hasField(field); |
||||
} |
||||
|
||||
public MergeTarget setField(Descriptors.FieldDescriptor field, |
||||
Object value) { |
||||
builder.setField(field, value); |
||||
return this; |
||||
} |
||||
|
||||
public MergeTarget clearField(Descriptors.FieldDescriptor field) { |
||||
builder.clearField(field); |
||||
return this; |
||||
} |
||||
|
||||
public MergeTarget setRepeatedField( |
||||
Descriptors.FieldDescriptor field, int index, Object value) { |
||||
builder.setRepeatedField(field, index, value); |
||||
return this; |
||||
} |
||||
|
||||
public MergeTarget addRepeatedField( |
||||
Descriptors.FieldDescriptor field, Object value) { |
||||
builder.addRepeatedField(field, value); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasOneof(Descriptors.OneofDescriptor oneof) { |
||||
return builder.hasOneof(oneof); |
||||
} |
||||
|
||||
@Override |
||||
public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { |
||||
builder.clearOneof(oneof); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { |
||||
return builder.getOneofFieldDescriptor(oneof); |
||||
} |
||||
|
||||
public ContainerType getContainerType() { |
||||
return ContainerType.MESSAGE; |
||||
} |
||||
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByName( |
||||
ExtensionRegistry registry, String name) { |
||||
return registry.findImmutableExtensionByName(name); |
||||
} |
||||
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByNumber( |
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType, |
||||
int fieldNumber) { |
||||
return registry.findImmutableExtensionByNumber(containingType, |
||||
fieldNumber); |
||||
} |
||||
|
||||
public Object parseGroup(CodedInputStream input, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
Descriptors.FieldDescriptor field, Message defaultInstance) |
||||
throws IOException { |
||||
Message.Builder subBuilder; |
||||
// When default instance is not null. The field is an extension field.
|
||||
if (defaultInstance != null) { |
||||
subBuilder = defaultInstance.newBuilderForType(); |
||||
} else { |
||||
subBuilder = builder.newBuilderForField(field); |
||||
} |
||||
if (!field.isRepeated()) { |
||||
Message originalMessage = (Message) getField(field); |
||||
if (originalMessage != null) { |
||||
subBuilder.mergeFrom(originalMessage); |
||||
} |
||||
} |
||||
input.readGroup(field.getNumber(), subBuilder, extensionRegistry); |
||||
return subBuilder.buildPartial(); |
||||
} |
||||
|
||||
public Object parseMessage(CodedInputStream input, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
Descriptors.FieldDescriptor field, Message defaultInstance) |
||||
throws IOException { |
||||
Message.Builder subBuilder; |
||||
// When default instance is not null. The field is an extension field.
|
||||
if (defaultInstance != null) { |
||||
subBuilder = defaultInstance.newBuilderForType(); |
||||
} else { |
||||
subBuilder = builder.newBuilderForField(field); |
||||
} |
||||
if (!field.isRepeated()) { |
||||
Message originalMessage = (Message) getField(field); |
||||
if (originalMessage != null) { |
||||
subBuilder.mergeFrom(originalMessage); |
||||
} |
||||
} |
||||
input.readMessage(subBuilder, extensionRegistry); |
||||
return subBuilder.buildPartial(); |
||||
} |
||||
|
||||
public Object parseMessageFromBytes(ByteString bytes, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
Descriptors.FieldDescriptor field, Message defaultInstance) |
||||
throws IOException { |
||||
Message.Builder subBuilder; |
||||
// When default instance is not null. The field is an extension field.
|
||||
if (defaultInstance != null) { |
||||
subBuilder = defaultInstance.newBuilderForType(); |
||||
} else { |
||||
subBuilder = builder.newBuilderForField(field); |
||||
} |
||||
if (!field.isRepeated()) { |
||||
Message originalMessage = (Message) getField(field); |
||||
if (originalMessage != null) { |
||||
subBuilder.mergeFrom(originalMessage); |
||||
} |
||||
} |
||||
subBuilder.mergeFrom(bytes, extensionRegistry); |
||||
return subBuilder.buildPartial(); |
||||
} |
||||
|
||||
public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field, |
||||
Message defaultInstance) { |
||||
if (defaultInstance != null) { |
||||
return new BuilderAdapter( |
||||
defaultInstance.newBuilderForType()); |
||||
} else { |
||||
return new BuilderAdapter(builder.newBuilderForField(field)); |
||||
} |
||||
} |
||||
|
||||
public Object readPrimitiveField( |
||||
CodedInputStream input, WireFormat.FieldType type, |
||||
boolean checkUtf8) throws IOException { |
||||
return FieldSet.readPrimitiveField(input, type, checkUtf8); |
||||
} |
||||
|
||||
public Object finish() { |
||||
return builder.buildPartial(); |
||||
} |
||||
} |
||||
|
||||
|
||||
static class ExtensionAdapter implements MergeTarget { |
||||
|
||||
private final FieldSet<Descriptors.FieldDescriptor> extensions; |
||||
|
||||
ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) { |
||||
this.extensions = extensions; |
||||
} |
||||
|
||||
public Descriptors.Descriptor getDescriptorForType() { |
||||
throw new UnsupportedOperationException( |
||||
"getDescriptorForType() called on FieldSet object"); |
||||
} |
||||
|
||||
public Object getField(Descriptors.FieldDescriptor field) { |
||||
return extensions.getField(field); |
||||
} |
||||
|
||||
public boolean hasField(Descriptors.FieldDescriptor field) { |
||||
return extensions.hasField(field); |
||||
} |
||||
|
||||
public MergeTarget setField(Descriptors.FieldDescriptor field, |
||||
Object value) { |
||||
extensions.setField(field, value); |
||||
return this; |
||||
} |
||||
|
||||
public MergeTarget clearField(Descriptors.FieldDescriptor field) { |
||||
extensions.clearField(field); |
||||
return this; |
||||
} |
||||
|
||||
public MergeTarget setRepeatedField( |
||||
Descriptors.FieldDescriptor field, int index, Object value) { |
||||
extensions.setRepeatedField(field, index, value); |
||||
return this; |
||||
} |
||||
|
||||
public MergeTarget addRepeatedField( |
||||
Descriptors.FieldDescriptor field, Object value) { |
||||
extensions.addRepeatedField(field, value); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasOneof(Descriptors.OneofDescriptor oneof) { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { |
||||
// Nothing to clear.
|
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { |
||||
return null; |
||||
} |
||||
|
||||
public ContainerType getContainerType() { |
||||
return ContainerType.EXTENSION_SET; |
||||
} |
||||
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByName( |
||||
ExtensionRegistry registry, String name) { |
||||
return registry.findImmutableExtensionByName(name); |
||||
} |
||||
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByNumber( |
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType, |
||||
int fieldNumber) { |
||||
return registry.findImmutableExtensionByNumber(containingType, |
||||
fieldNumber); |
||||
} |
||||
|
||||
public Object parseGroup(CodedInputStream input, |
||||
ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, |
||||
Message defaultInstance) throws IOException { |
||||
Message.Builder subBuilder = |
||||
defaultInstance.newBuilderForType(); |
||||
if (!field.isRepeated()) { |
||||
Message originalMessage = (Message) getField(field); |
||||
if (originalMessage != null) { |
||||
subBuilder.mergeFrom(originalMessage); |
||||
} |
||||
} |
||||
input.readGroup(field.getNumber(), subBuilder, registry); |
||||
return subBuilder.buildPartial(); |
||||
} |
||||
|
||||
public Object parseMessage(CodedInputStream input, |
||||
ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, |
||||
Message defaultInstance) throws IOException { |
||||
Message.Builder subBuilder = |
||||
defaultInstance.newBuilderForType(); |
||||
if (!field.isRepeated()) { |
||||
Message originalMessage = (Message) getField(field); |
||||
if (originalMessage != null) { |
||||
subBuilder.mergeFrom(originalMessage); |
||||
} |
||||
} |
||||
input.readMessage(subBuilder, registry); |
||||
return subBuilder.buildPartial(); |
||||
} |
||||
|
||||
public Object parseMessageFromBytes(ByteString bytes, |
||||
ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, |
||||
Message defaultInstance) throws IOException { |
||||
Message.Builder subBuilder = defaultInstance.newBuilderForType(); |
||||
if (!field.isRepeated()) { |
||||
Message originalMessage = (Message) getField(field); |
||||
if (originalMessage != null) { |
||||
subBuilder.mergeFrom(originalMessage); |
||||
} |
||||
} |
||||
subBuilder.mergeFrom(bytes, registry); |
||||
return subBuilder.buildPartial(); |
||||
} |
||||
|
||||
public MergeTarget newMergeTargetForField( |
||||
Descriptors.FieldDescriptor descriptor, Message defaultInstance) { |
||||
throw new UnsupportedOperationException( |
||||
"newMergeTargetForField() called on FieldSet object"); |
||||
} |
||||
|
||||
public Object readPrimitiveField( |
||||
CodedInputStream input, WireFormat.FieldType type, |
||||
boolean checkUtf8) throws IOException { |
||||
return FieldSet.readPrimitiveField(input, type, checkUtf8); |
||||
} |
||||
|
||||
public Object finish() { |
||||
throw new UnsupportedOperationException( |
||||
"finish() called on FieldSet object"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Parses a single field into MergeTarget. The target can be Message.Builder, |
||||
* FieldSet or MutableMessage. |
||||
* |
||||
* Package-private because it is used by GeneratedMessage.ExtendableMessage. |
||||
* |
||||
* @param tag The tag, which should have already been read. |
||||
* @return {@code true} unless the tag is an end-group tag. |
||||
*/ |
||||
static boolean mergeFieldFrom( |
||||
CodedInputStream input, |
||||
UnknownFieldSet.Builder unknownFields, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
Descriptors.Descriptor type, |
||||
MergeTarget target, |
||||
int tag) throws IOException { |
||||
if (type.getOptions().getMessageSetWireFormat() && |
||||
tag == WireFormat.MESSAGE_SET_ITEM_TAG) { |
||||
mergeMessageSetExtensionFromCodedStream( |
||||
input, unknownFields, extensionRegistry, type, target); |
||||
return true; |
||||
} |
||||
|
||||
final int wireType = WireFormat.getTagWireType(tag); |
||||
final int fieldNumber = WireFormat.getTagFieldNumber(tag); |
||||
|
||||
final Descriptors.FieldDescriptor field; |
||||
Message defaultInstance = null; |
||||
|
||||
if (type.isExtensionNumber(fieldNumber)) { |
||||
// extensionRegistry may be either ExtensionRegistry or
|
||||
// ExtensionRegistryLite. Since the type we are parsing is a full
|
||||
// message, only a full ExtensionRegistry could possibly contain
|
||||
// extensions of it. Otherwise we will treat the registry as if it
|
||||
// were empty.
|
||||
if (extensionRegistry instanceof ExtensionRegistry) { |
||||
final ExtensionRegistry.ExtensionInfo extension = |
||||
target.findExtensionByNumber((ExtensionRegistry) extensionRegistry, |
||||
type, fieldNumber); |
||||
if (extension == null) { |
||||
field = null; |
||||
} else { |
||||
field = extension.descriptor; |
||||
defaultInstance = extension.defaultInstance; |
||||
if (defaultInstance == null && |
||||
field.getJavaType() |
||||
== Descriptors.FieldDescriptor.JavaType.MESSAGE) { |
||||
throw new IllegalStateException( |
||||
"Message-typed extension lacked default instance: " + |
||||
field.getFullName()); |
||||
} |
||||
} |
||||
} else { |
||||
field = null; |
||||
} |
||||
} else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) { |
||||
field = type.findFieldByNumber(fieldNumber); |
||||
} else { |
||||
field = null; |
||||
} |
||||
|
||||
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 (packed) { |
||||
final int length = input.readRawVarint32(); |
||||
final int limit = input.pushLimit(length); |
||||
if (field.getLiteType() == WireFormat.FieldType.ENUM) { |
||||
while (input.getBytesUntilLimit() > 0) { |
||||
final int rawValue = input.readEnum(); |
||||
final Object value = field.getEnumType().findValueByNumber(rawValue); |
||||
if (value == null) { |
||||
// If the number isn't recognized as a valid value for this
|
||||
// enum, drop it (don't even add it to unknownFields).
|
||||
return true; |
||||
} |
||||
target.addRepeatedField(field, value); |
||||
} |
||||
} else { |
||||
while (input.getBytesUntilLimit() > 0) { |
||||
final Object value = |
||||
target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check()); |
||||
target.addRepeatedField(field, value); |
||||
} |
||||
} |
||||
input.popLimit(limit); |
||||
} else { |
||||
final Object value; |
||||
switch (field.getType()) { |
||||
case GROUP: { |
||||
value = target |
||||
.parseGroup(input, extensionRegistry, field, defaultInstance); |
||||
break; |
||||
} |
||||
case MESSAGE: { |
||||
value = target |
||||
.parseMessage(input, extensionRegistry, field, defaultInstance); |
||||
break; |
||||
} |
||||
case ENUM: |
||||
final int rawValue = input.readEnum(); |
||||
value = field.getEnumType().findValueByNumber(rawValue); |
||||
// If the number isn't recognized as a valid value for this enum,
|
||||
// drop it.
|
||||
if (value == null) { |
||||
unknownFields.mergeVarintField(fieldNumber, rawValue); |
||||
return true; |
||||
} |
||||
break; |
||||
default: |
||||
value = target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check()); |
||||
break; |
||||
} |
||||
|
||||
if (field.isRepeated()) { |
||||
target.addRepeatedField(field, value); |
||||
} else { |
||||
target.setField(field, value); |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into |
||||
* MergeTarget. |
||||
*/ |
||||
private static void mergeMessageSetExtensionFromCodedStream( |
||||
CodedInputStream input, |
||||
UnknownFieldSet.Builder unknownFields, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
Descriptors.Descriptor type, |
||||
MergeTarget target) throws IOException { |
||||
|
||||
// The wire format for MessageSet is:
|
||||
// message MessageSet {
|
||||
// repeated group Item = 1 {
|
||||
// required int32 typeId = 2;
|
||||
// required bytes message = 3;
|
||||
// }
|
||||
// }
|
||||
// "typeId" is the extension's field number. The extension can only be
|
||||
// a message type, where "message" contains the encoded bytes of that
|
||||
// message.
|
||||
//
|
||||
// In practice, we will probably never see a MessageSet item in which
|
||||
// the message appears before the type ID, or where either field does not
|
||||
// appear exactly once. However, in theory such cases are valid, so we
|
||||
// should be prepared to accept them.
|
||||
|
||||
int typeId = 0; |
||||
ByteString rawBytes = null; // If we encounter "message" before "typeId"
|
||||
ExtensionRegistry.ExtensionInfo extension = null; |
||||
|
||||
// Read bytes from input, if we get it's type first then parse it eagerly,
|
||||
// otherwise we store the raw bytes in a local variable.
|
||||
while (true) { |
||||
final int tag = input.readTag(); |
||||
if (tag == 0) { |
||||
break; |
||||
} |
||||
|
||||
if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { |
||||
typeId = input.readUInt32(); |
||||
if (typeId != 0) { |
||||
// extensionRegistry may be either ExtensionRegistry or
|
||||
// ExtensionRegistryLite. Since the type we are parsing is a full
|
||||
// message, only a full ExtensionRegistry could possibly contain
|
||||
// extensions of it. Otherwise we will treat the registry as if it
|
||||
// were empty.
|
||||
if (extensionRegistry instanceof ExtensionRegistry) { |
||||
extension = target.findExtensionByNumber( |
||||
(ExtensionRegistry) extensionRegistry, type, typeId); |
||||
} |
||||
} |
||||
|
||||
} else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { |
||||
if (typeId != 0) { |
||||
if (extension != null && |
||||
ExtensionRegistryLite.isEagerlyParseMessageSets()) { |
||||
// We already know the type, so we can parse directly from the
|
||||
// input with no copying. Hooray!
|
||||
eagerlyMergeMessageSetExtension( |
||||
input, extension, extensionRegistry, target); |
||||
rawBytes = null; |
||||
continue; |
||||
} |
||||
} |
||||
// We haven't seen a type ID yet or we want parse message lazily.
|
||||
rawBytes = input.readBytes(); |
||||
|
||||
} else { // Unknown tag. Skip it.
|
||||
if (!input.skipField(tag)) { |
||||
break; // End of group
|
||||
} |
||||
} |
||||
} |
||||
input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG); |
||||
|
||||
// Process the raw bytes.
|
||||
if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
|
||||
if (extension != null) { // We known the type
|
||||
mergeMessageSetExtensionFromBytes( |
||||
rawBytes, extension, extensionRegistry, target); |
||||
} else { // We don't know how to parse this. Ignore it.
|
||||
if (rawBytes != null) { |
||||
unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder() |
||||
.addLengthDelimited(rawBytes).build()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static void mergeMessageSetExtensionFromBytes( |
||||
ByteString rawBytes, |
||||
ExtensionRegistry.ExtensionInfo extension, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
MergeTarget target) throws IOException { |
||||
|
||||
Descriptors.FieldDescriptor field = extension.descriptor; |
||||
boolean hasOriginalValue = target.hasField(field); |
||||
|
||||
if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { |
||||
// If the field already exists, we just parse the field.
|
||||
Object value = target.parseMessageFromBytes( |
||||
rawBytes, extensionRegistry,field, extension.defaultInstance); |
||||
target.setField(field, value); |
||||
} else { |
||||
// Use LazyField to load MessageSet lazily.
|
||||
LazyField lazyField = new LazyField( |
||||
extension.defaultInstance, extensionRegistry, rawBytes); |
||||
target.setField(field, lazyField); |
||||
} |
||||
} |
||||
|
||||
private static void eagerlyMergeMessageSetExtension( |
||||
CodedInputStream input, |
||||
ExtensionRegistry.ExtensionInfo extension, |
||||
ExtensionRegistryLite extensionRegistry, |
||||
MergeTarget target) throws IOException { |
||||
Descriptors.FieldDescriptor field = extension.descriptor; |
||||
Object value = target.parseMessage(input, extensionRegistry, field, |
||||
extension.defaultInstance); |
||||
target.setField(field, value); |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* An interface extending {@code List<String>} used for repeated string fields |
||||
* to provide optional access to the data as a list of ByteStrings. The |
||||
* underlying implementation stores values as either ByteStrings or Strings |
||||
* (see {@link LazyStringArrayList}) depending on how the value was initialized |
||||
* or last read, and it is often more efficient to deal with lists of |
||||
* ByteStrings when handling protos that have been deserialized from bytes. |
||||
*/ |
||||
public interface ProtocolStringList extends List<String> { |
||||
|
||||
/** Returns a view of the data as a list of ByteStrings. */ |
||||
List<ByteString> asByteStringList(); |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,141 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import proto2_test_check_utf8.TestCheckUtf8.BytesWrapper; |
||||
import proto2_test_check_utf8.TestCheckUtf8.StringWrapper; |
||||
import proto2_test_check_utf8_size.TestCheckUtf8Size.BytesWrapperSize; |
||||
import proto2_test_check_utf8_size.TestCheckUtf8Size.StringWrapperSize; |
||||
import junit.framework.TestCase; |
||||
|
||||
/** |
||||
* Test that protos generated with file option java_string_check_utf8 do in |
||||
* fact perform appropriate UTF-8 checks. |
||||
* |
||||
* @author jbaum@google.com (Jacob Butcher) |
||||
*/ |
||||
public class CheckUtf8Test extends TestCase { |
||||
|
||||
private static final String UTF8_BYTE_STRING_TEXT = "some text"; |
||||
private static final ByteString UTF8_BYTE_STRING = |
||||
ByteString.copyFromUtf8(UTF8_BYTE_STRING_TEXT); |
||||
private static final ByteString NON_UTF8_BYTE_STRING = |
||||
ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte.
|
||||
|
||||
public void testBuildRequiredStringWithGoodUtf8() throws Exception { |
||||
assertEquals(UTF8_BYTE_STRING_TEXT, |
||||
StringWrapper.newBuilder().setReqBytes(UTF8_BYTE_STRING).getReq()); |
||||
} |
||||
|
||||
public void testParseRequiredStringWithGoodUtf8() throws Exception { |
||||
ByteString serialized = |
||||
BytesWrapper.newBuilder().setReq(UTF8_BYTE_STRING).build().toByteString(); |
||||
assertEquals(UTF8_BYTE_STRING_TEXT, |
||||
StringWrapper.PARSER.parseFrom(serialized).getReq()); |
||||
} |
||||
|
||||
public void testBuildRequiredStringWithBadUtf8() throws Exception { |
||||
try { |
||||
StringWrapper.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING); |
||||
fail("Expected IllegalArgumentException for non UTF-8 byte string."); |
||||
} catch (IllegalArgumentException exception) { |
||||
assertEquals("Byte string is not UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testBuildOptionalStringWithBadUtf8() throws Exception { |
||||
try { |
||||
StringWrapper.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING); |
||||
fail("Expected IllegalArgumentException for non UTF-8 byte string."); |
||||
} catch (IllegalArgumentException exception) { |
||||
assertEquals("Byte string is not UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testBuildRepeatedStringWithBadUtf8() throws Exception { |
||||
try { |
||||
StringWrapper.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING); |
||||
fail("Expected IllegalArgumentException for non UTF-8 byte string."); |
||||
} catch (IllegalArgumentException exception) { |
||||
assertEquals("Byte string is not UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testParseRequiredStringWithBadUtf8() throws Exception { |
||||
ByteString serialized = |
||||
BytesWrapper.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString(); |
||||
try { |
||||
StringWrapper.PARSER.parseFrom(serialized); |
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string."); |
||||
} catch (InvalidProtocolBufferException exception) { |
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testBuildRequiredStringWithBadUtf8Size() throws Exception { |
||||
try { |
||||
StringWrapperSize.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING); |
||||
fail("Expected IllegalArgumentException for non UTF-8 byte string."); |
||||
} catch (IllegalArgumentException exception) { |
||||
assertEquals("Byte string is not UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testBuildOptionalStringWithBadUtf8Size() throws Exception { |
||||
try { |
||||
StringWrapperSize.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING); |
||||
fail("Expected IllegalArgumentException for non UTF-8 byte string."); |
||||
} catch (IllegalArgumentException exception) { |
||||
assertEquals("Byte string is not UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testBuildRepeatedStringWithBadUtf8Size() throws Exception { |
||||
try { |
||||
StringWrapperSize.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING); |
||||
fail("Expected IllegalArgumentException for non UTF-8 byte string."); |
||||
} catch (IllegalArgumentException exception) { |
||||
assertEquals("Byte string is not UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void testParseRequiredStringWithBadUtf8Size() throws Exception { |
||||
ByteString serialized = |
||||
BytesWrapperSize.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString(); |
||||
try { |
||||
StringWrapperSize.PARSER.parseFrom(serialized); |
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string."); |
||||
} catch (InvalidProtocolBufferException exception) { |
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage()); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,134 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import protobuf_unittest.UnittestProto.TestAllExtensions; |
||||
import protobuf_unittest.UnittestProto.TestAllTypes; |
||||
|
||||
import java.io.IOException; |
||||
import junit.framework.TestCase; |
||||
|
||||
/** |
||||
* Unit test for {@link LazyFieldLite}. |
||||
* |
||||
* @author xiangl@google.com (Xiang Li) |
||||
*/ |
||||
public class LazyFieldLiteTest extends TestCase { |
||||
|
||||
public void testGetValue() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); |
||||
} |
||||
|
||||
public void testGetValueEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
assertEquals(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); |
||||
} |
||||
|
||||
public void testSetValue() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); |
||||
message = lazyField.getValue(TestAllTypes.getDefaultInstance()); |
||||
changeValue(lazyField); |
||||
assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); |
||||
} |
||||
|
||||
public void testSetValueEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); |
||||
MessageLite value = lazyField.getValue(TestAllExtensions.getDefaultInstance()); |
||||
changeValue(lazyField); |
||||
assertEquals(value, lazyField.getValue(TestAllExtensions.getDefaultInstance())); |
||||
} |
||||
|
||||
public void testGetSerializedSize() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
assertEquals(message.getSerializedSize(), lazyField.getSerializedSize()); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize()); |
||||
} |
||||
|
||||
public void testGetSerializedSizeEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
assertEquals(message.getSerializedSize(), lazyField.getSerializedSize()); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize()); |
||||
} |
||||
|
||||
public void testGetByteString() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
assertEquals(message.toByteString(), lazyField.toByteString()); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message.toByteString(), lazyField.toByteString()); |
||||
} |
||||
|
||||
public void testGetByteStringEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); |
||||
assertEquals(message.toByteString(), lazyField.toByteString()); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message.toByteString(), lazyField.toByteString()); |
||||
} |
||||
|
||||
|
||||
// Help methods.
|
||||
|
||||
private LazyFieldLite createLazyFieldLiteFromMessage(MessageLite message) { |
||||
ByteString bytes = message.toByteString(); |
||||
return new LazyFieldLite(TestUtil.getExtensionRegistry(), bytes); |
||||
} |
||||
|
||||
private void changeValue(LazyFieldLite lazyField) { |
||||
TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder(); |
||||
builder.addRepeatedBool(true); |
||||
MessageLite newMessage = builder.build(); |
||||
lazyField.setValue(newMessage); |
||||
} |
||||
|
||||
private void assertNotEqual(Object unexpected, Object actual) { |
||||
assertFalse(unexpected == actual |
||||
|| (unexpected != null && unexpected.equals(actual))); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,121 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import protobuf_unittest.UnittestProto.TestAllExtensions; |
||||
import protobuf_unittest.UnittestProto.TestAllTypes; |
||||
|
||||
import java.io.IOException; |
||||
import junit.framework.TestCase; |
||||
|
||||
/** |
||||
* Unit test for {@link LazyField}. |
||||
* |
||||
* @author xiangl@google.com (Xiang Li) |
||||
*/ |
||||
public class LazyFieldTest extends TestCase { |
||||
public void testHashCode() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyField lazyField = |
||||
createLazyFieldFromMessage(message); |
||||
assertEquals(message.hashCode(), lazyField.hashCode()); |
||||
lazyField.getValue(); |
||||
assertEquals(message.hashCode(), lazyField.hashCode()); |
||||
changeValue(lazyField); |
||||
// make sure two messages have different hash code
|
||||
assertNotEqual(message.hashCode(), lazyField.hashCode()); |
||||
} |
||||
|
||||
public void testHashCodeEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyField lazyField = createLazyFieldFromMessage(message); |
||||
assertEquals(message.hashCode(), lazyField.hashCode()); |
||||
lazyField.getValue(); |
||||
assertEquals(message.hashCode(), lazyField.hashCode()); |
||||
changeValue(lazyField); |
||||
// make sure two messages have different hash code
|
||||
assertNotEqual(message.hashCode(), lazyField.hashCode()); |
||||
} |
||||
|
||||
public void testGetValue() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyField lazyField = createLazyFieldFromMessage(message); |
||||
assertEquals(message, lazyField.getValue()); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message, lazyField.getValue()); |
||||
} |
||||
|
||||
public void testGetValueEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyField lazyField = createLazyFieldFromMessage(message); |
||||
assertEquals(message, lazyField.getValue()); |
||||
changeValue(lazyField); |
||||
assertNotEqual(message, lazyField.getValue()); |
||||
} |
||||
|
||||
public void testEqualsObject() { |
||||
MessageLite message = TestUtil.getAllSet(); |
||||
LazyField lazyField = createLazyFieldFromMessage(message); |
||||
assertTrue(lazyField.equals(message)); |
||||
changeValue(lazyField); |
||||
assertFalse(lazyField.equals(message)); |
||||
assertFalse(message.equals(lazyField.getValue())); |
||||
} |
||||
|
||||
public void testEqualsObjectEx() throws Exception { |
||||
TestAllExtensions message = TestUtil.getAllExtensionsSet(); |
||||
LazyField lazyField = createLazyFieldFromMessage(message); |
||||
assertTrue(lazyField.equals(message)); |
||||
changeValue(lazyField); |
||||
assertFalse(lazyField.equals(message)); |
||||
assertFalse(message.equals(lazyField.getValue())); |
||||
} |
||||
|
||||
// Help methods.
|
||||
|
||||
private LazyField createLazyFieldFromMessage(MessageLite message) { |
||||
ByteString bytes = message.toByteString(); |
||||
return new LazyField(message.getDefaultInstanceForType(), |
||||
TestUtil.getExtensionRegistry(), bytes); |
||||
} |
||||
|
||||
private void changeValue(LazyField lazyField) { |
||||
TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder(); |
||||
builder.addRepeatedBool(true); |
||||
MessageLite newMessage = builder.build(); |
||||
lazyField.setValue(newMessage); |
||||
} |
||||
|
||||
private void assertNotEqual(Object unexpected, Object actual) { |
||||
assertFalse(unexpected == actual |
||||
|| (unexpected != null && unexpected.equals(actual))); |
||||
} |
||||
} |
@ -0,0 +1,319 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import protobuf_unittest.LazyFieldsLite.LazyInnerMessageLite; |
||||
import protobuf_unittest.LazyFieldsLite.LazyMessageLite; |
||||
import protobuf_unittest.LazyFieldsLite.LazyNestedInnerMessageLite; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.easymock.classextension.EasyMock; |
||||
|
||||
import java.util.ArrayList; |
||||
|
||||
/** |
||||
* Unit test for messages with lazy fields. |
||||
* |
||||
* @author niwasaki@google.com (Naoki Iwasaki) |
||||
*/ |
||||
public class LazyMessageLiteTest extends TestCase { |
||||
|
||||
private Parser<LazyInnerMessageLite> originalLazyInnerMessageLiteParser; |
||||
|
||||
@Override |
||||
protected void setUp() throws Exception { |
||||
super.setUp(); |
||||
|
||||
originalLazyInnerMessageLiteParser = LazyInnerMessageLite.PARSER; |
||||
} |
||||
|
||||
@Override |
||||
protected void tearDown() throws Exception { |
||||
LazyInnerMessageLite.PARSER = originalLazyInnerMessageLiteParser; |
||||
|
||||
super.tearDown(); |
||||
} |
||||
|
||||
public void testSetValues() { |
||||
LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder() |
||||
.setNum(3) |
||||
.build(); |
||||
LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder() |
||||
.setNum(2) |
||||
.setNested(nested) |
||||
.build(); |
||||
LazyMessageLite outer = LazyMessageLite.newBuilder() |
||||
.setNum(1) |
||||
.setInner(inner) |
||||
.setOneofNum(123) |
||||
.setOneofInner(inner) |
||||
.build(); |
||||
|
||||
assertEquals(1, outer.getNum()); |
||||
assertEquals(421, outer.getNumWithDefault()); |
||||
|
||||
assertEquals(2, outer.getInner().getNum()); |
||||
assertEquals(42, outer.getInner().getNumWithDefault()); |
||||
|
||||
assertEquals(3, outer.getInner().getNested().getNum()); |
||||
assertEquals(4, outer.getInner().getNested().getNumWithDefault()); |
||||
|
||||
assertFalse(outer.hasOneofNum()); |
||||
assertTrue(outer.hasOneofInner()); |
||||
|
||||
assertEquals(2, outer.getOneofInner().getNum()); |
||||
assertEquals(42, outer.getOneofInner().getNumWithDefault()); |
||||
assertEquals(3, outer.getOneofInner().getNested().getNum()); |
||||
assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault()); |
||||
} |
||||
|
||||
public void testSetRepeatedValues() { |
||||
LazyMessageLite outer = LazyMessageLite.newBuilder() |
||||
.setNum(1) |
||||
.addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119)) |
||||
.addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122)) |
||||
.build(); |
||||
|
||||
assertEquals(1, outer.getNum()); |
||||
assertEquals(2, outer.getRepeatedInnerCount()); |
||||
assertEquals(119, outer.getRepeatedInner(0).getNum()); |
||||
assertEquals(122, outer.getRepeatedInner(1).getNum()); |
||||
} |
||||
|
||||
public void testAddAll() { |
||||
ArrayList<LazyInnerMessageLite> inners = new ArrayList<LazyInnerMessageLite>(); |
||||
int count = 4; |
||||
for (int i = 0; i < count; i++) { |
||||
LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder() |
||||
.setNum(i) |
||||
.build(); |
||||
inners.add(inner); |
||||
} |
||||
|
||||
LazyMessageLite outer = LazyMessageLite.newBuilder() |
||||
.addAllRepeatedInner(inners) |
||||
.build(); |
||||
assertEquals(count, outer.getRepeatedInnerCount()); |
||||
for (int i = 0; i < count; i++) { |
||||
assertEquals(i, outer.getRepeatedInner(i).getNum()); |
||||
} |
||||
} |
||||
|
||||
public void testGetDefaultValues() { |
||||
LazyMessageLite outer = LazyMessageLite.newBuilder() |
||||
.build(); |
||||
|
||||
assertEquals(0, outer.getNum()); |
||||
assertEquals(421, outer.getNumWithDefault()); |
||||
|
||||
assertEquals(0, outer.getInner().getNum()); |
||||
assertEquals(42, outer.getInner().getNumWithDefault()); |
||||
|
||||
assertEquals(0, outer.getInner().getNested().getNum()); |
||||
assertEquals(4, outer.getInner().getNested().getNumWithDefault()); |
||||
|
||||
assertEquals(0, outer.getOneofNum()); |
||||
|
||||
assertEquals(0, outer.getOneofInner().getNum()); |
||||
assertEquals(42, outer.getOneofInner().getNumWithDefault()); |
||||
assertEquals(0, outer.getOneofInner().getNested().getNum()); |
||||
assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault()); |
||||
} |
||||
|
||||
public void testClearValues() { |
||||
LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder() |
||||
.setNum(115) |
||||
.build(); |
||||
|
||||
LazyMessageLite.Builder outerBuilder = LazyMessageLite.newBuilder(); |
||||
|
||||
assertEquals(0, outerBuilder.build().getNum()); |
||||
|
||||
|
||||
// Set/Clear num
|
||||
outerBuilder.setNum(100); |
||||
|
||||
assertEquals(100, outerBuilder.build().getNum()); |
||||
assertEquals(421, outerBuilder.build().getNumWithDefault()); |
||||
assertFalse(outerBuilder.build().hasInner()); |
||||
|
||||
outerBuilder.clearNum(); |
||||
|
||||
assertEquals(0, outerBuilder.build().getNum()); |
||||
assertEquals(421, outerBuilder.build().getNumWithDefault()); |
||||
assertFalse(outerBuilder.build().hasInner()); |
||||
|
||||
|
||||
// Set/Clear all
|
||||
outerBuilder.setNum(100) |
||||
.setInner(inner) |
||||
.addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119)) |
||||
.addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122)) |
||||
.setOneofInner(LazyInnerMessageLite.newBuilder().setNum(123)); |
||||
|
||||
LazyMessageLite outer = outerBuilder.build(); |
||||
assertEquals(100, outer.getNum()); |
||||
assertEquals(421, outer.getNumWithDefault()); |
||||
assertTrue(outer.hasInner()); |
||||
assertEquals(115, outer.getInner().getNum()); |
||||
assertEquals(2, outer.getRepeatedInnerCount()); |
||||
assertEquals(119, outer.getRepeatedInner(0).getNum()); |
||||
assertEquals(122, outer.getRepeatedInner(1).getNum()); |
||||
assertTrue(outer.hasOneofInner()); |
||||
assertEquals(123, outer.getOneofInner().getNum()); |
||||
|
||||
outerBuilder.clear(); |
||||
|
||||
outer = outerBuilder.build(); |
||||
|
||||
assertEquals(0, outer.getNum()); |
||||
assertEquals(421, outer.getNumWithDefault()); |
||||
assertFalse(outer.hasInner()); |
||||
assertEquals(0, outer.getRepeatedInnerCount()); |
||||
assertFalse(outer.hasOneofInner()); |
||||
assertEquals(0, outer.getOneofInner().getNum()); |
||||
} |
||||
|
||||
public void testMergeValues() { |
||||
LazyMessageLite outerBase = LazyMessageLite.newBuilder() |
||||
.setNumWithDefault(122) |
||||
.build(); |
||||
|
||||
LazyInnerMessageLite innerMerging = LazyInnerMessageLite.newBuilder() |
||||
.setNum(115) |
||||
.build(); |
||||
LazyMessageLite outerMerging = LazyMessageLite.newBuilder() |
||||
.setNum(119) |
||||
.setInner(innerMerging) |
||||
.setOneofInner(innerMerging) |
||||
.build(); |
||||
|
||||
LazyMessageLite merged = LazyMessageLite |
||||
.newBuilder(outerBase) |
||||
.mergeFrom(outerMerging) |
||||
.build(); |
||||
assertEquals(119, merged.getNum()); |
||||
assertEquals(122, merged.getNumWithDefault()); |
||||
assertEquals(115, merged.getInner().getNum()); |
||||
assertEquals(42, merged.getInner().getNumWithDefault()); |
||||
assertEquals(115, merged.getOneofInner().getNum()); |
||||
assertEquals(42, merged.getOneofInner().getNumWithDefault()); |
||||
} |
||||
|
||||
public void testMergeDefaultValues() { |
||||
LazyInnerMessageLite innerBase = LazyInnerMessageLite.newBuilder() |
||||
.setNum(115) |
||||
.build(); |
||||
LazyMessageLite outerBase = LazyMessageLite.newBuilder() |
||||
.setNum(119) |
||||
.setNumWithDefault(122) |
||||
.setInner(innerBase) |
||||
.setOneofInner(innerBase) |
||||
.build(); |
||||
|
||||
LazyMessageLite outerMerging = LazyMessageLite.newBuilder() |
||||
.build(); |
||||
|
||||
LazyMessageLite merged = LazyMessageLite |
||||
.newBuilder(outerBase) |
||||
.mergeFrom(outerMerging) |
||||
.build(); |
||||
// Merging default-instance shouldn't overwrite values in the base message.
|
||||
assertEquals(119, merged.getNum()); |
||||
assertEquals(122, merged.getNumWithDefault()); |
||||
assertEquals(115, merged.getInner().getNum()); |
||||
assertEquals(42, merged.getInner().getNumWithDefault()); |
||||
assertEquals(115, merged.getOneofInner().getNum()); |
||||
assertEquals(42, merged.getOneofInner().getNumWithDefault()); |
||||
} |
||||
|
||||
public void testSerialize() throws InvalidProtocolBufferException { |
||||
LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder() |
||||
.setNum(3) |
||||
.build(); |
||||
LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder() |
||||
.setNum(2) |
||||
.setNested(nested) |
||||
.build(); |
||||
LazyMessageLite outer = LazyMessageLite.newBuilder() |
||||
.setNum(1) |
||||
.setInner(inner) |
||||
.setOneofInner(inner) |
||||
.build(); |
||||
|
||||
ByteString bytes = outer.toByteString(); |
||||
assertEquals(bytes.size(), outer.getSerializedSize()); |
||||
|
||||
LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes); |
||||
|
||||
assertEquals(1, deserialized.getNum()); |
||||
assertEquals(421, deserialized.getNumWithDefault()); |
||||
|
||||
assertEquals(2, deserialized.getInner().getNum()); |
||||
assertEquals(42, deserialized.getInner().getNumWithDefault()); |
||||
|
||||
assertEquals(3, deserialized.getInner().getNested().getNum()); |
||||
assertEquals(4, deserialized.getInner().getNested().getNumWithDefault()); |
||||
|
||||
assertEquals(2, deserialized.getOneofInner().getNum()); |
||||
assertEquals(42, deserialized.getOneofInner().getNumWithDefault()); |
||||
assertEquals(3, deserialized.getOneofInner().getNested().getNum()); |
||||
assertEquals(4, deserialized.getOneofInner().getNested().getNumWithDefault()); |
||||
|
||||
assertEquals(bytes, deserialized.toByteString()); |
||||
} |
||||
|
||||
public void testLaziness() throws InvalidProtocolBufferException { |
||||
LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder() |
||||
.setNum(2) |
||||
.build(); |
||||
LazyMessageLite outer = LazyMessageLite.newBuilder() |
||||
.setNum(1) |
||||
.setInner(inner) |
||||
.setOneofInner(inner) |
||||
.build(); |
||||
ByteString bytes = outer.toByteString(); |
||||
|
||||
|
||||
// The parser for inner / oneofInner message shouldn't be used if
|
||||
// getInner / getOneofInner is not called.
|
||||
LazyInnerMessageLite.PARSER = EasyMock.createStrictMock(Parser.class); |
||||
|
||||
EasyMock.replay(LazyInnerMessageLite.PARSER); |
||||
|
||||
LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes); |
||||
assertEquals(1, deserialized.getNum()); |
||||
assertEquals(421, deserialized.getNumWithDefault()); |
||||
|
||||
EasyMock.verify(LazyInnerMessageLite.PARSER); |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf; |
||||
|
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar; |
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime; |
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
/** |
||||
* Test generate equal and hash methods for the lite runtime. |
||||
* |
||||
* @author pbogle@google.com Phil Bogle |
||||
*/ |
||||
public class LiteEqualsAndHashTest extends TestCase { |
||||
|
||||
public void testEquals() throws Exception { |
||||
// Since the generated equals and hashCode methods for lite messages are a
|
||||
// mostly complete subset of those for regular messages, we can mostly assume
|
||||
// that the generated methods are already thoroughly tested by the regular tests.
|
||||
|
||||
// This test mostly just verifies is that a proto with
|
||||
// optimize_for = LITE_RUNTIME and java_generates_equals_and_hash_compiles
|
||||
// correctly when linked only against the lite library.
|
||||
|
||||
// We do however do some basic testing to make sure that equals is actually
|
||||
// overriden to test for value equality rather than simple object equality.
|
||||
|
||||
// Check that two identical objs are equal.
|
||||
Foo foo1a = Foo.newBuilder() |
||||
.setValue(1) |
||||
.addBar(Bar.newBuilder().setName("foo1")) |
||||
.build(); |
||||
Foo foo1b = Foo.newBuilder() |
||||
.setValue(1) |
||||
.addBar(Bar.newBuilder().setName("foo1")) |
||||
.build(); |
||||
Foo foo2 = Foo.newBuilder() |
||||
.setValue(1) |
||||
.addBar(Bar.newBuilder().setName("foo2")) |
||||
.build(); |
||||
|
||||
// Check that equals is doing value rather than object equality.
|
||||
assertEquals(foo1a, foo1b); |
||||
assertEquals(foo1a.hashCode(), foo1b.hashCode()); |
||||
|
||||
// Check that a diffeent object is not equal.
|
||||
assertFalse(foo1a.equals(foo2)); |
||||
|
||||
// Check that two objects which have different types but the same field values are not
|
||||
// considered to be equal.
|
||||
Bar bar = Bar.newBuilder().setName("bar").build(); |
||||
BarPrime barPrime = BarPrime.newBuilder().setName("bar").build(); |
||||
assertFalse(bar.equals(barPrime)); |
||||
} |
||||
} |
@ -0,0 +1,61 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
// Author: Naoki Iwasaki (niwasaki@google.com) |
||||
// |
||||
// A proto file with lazy fields |
||||
|
||||
|
||||
package protobuf_unittest; |
||||
|
||||
option optimize_for = LITE_RUNTIME; |
||||
|
||||
message LazyMessageLite { |
||||
optional int32 num = 1; |
||||
optional int32 num_with_default = 2 [default = 421]; |
||||
optional LazyInnerMessageLite inner = 3 [lazy = true]; |
||||
repeated LazyInnerMessageLite repeated_inner = 4 [lazy = true]; |
||||
|
||||
oneof oneof_field { |
||||
int32 oneof_num = 5; |
||||
LazyInnerMessageLite oneof_inner = 6 [lazy = true]; |
||||
} |
||||
} |
||||
|
||||
message LazyInnerMessageLite { |
||||
optional int32 num = 1; |
||||
optional int32 num_with_default = 2 [default = 42]; |
||||
optional LazyNestedInnerMessageLite nested = 3 [lazy = true]; |
||||
} |
||||
|
||||
message LazyNestedInnerMessageLite { |
||||
optional int32 num = 1; |
||||
optional int32 num_with_default = 2 [default = 4]; |
||||
} |
@ -0,0 +1,38 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
package protobuf_unittest; |
||||
|
||||
|
||||
// This message's name is the same with the default outer class name of this |
||||
// proto file. It's used to test if the compiler can avoid this conflict |
||||
// correctly. |
||||
message OuterClassNameTest { |
||||
} |
@ -0,0 +1,42 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
package protobuf_unittest; |
||||
|
||||
|
||||
message TestMessage2 { |
||||
message NestedMessage { |
||||
// This message's name is the same with the default outer class name of this |
||||
// proto file. It's used to test if the compiler can avoid this conflict |
||||
// correctly. |
||||
message OuterClassNameTest2 { |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
package protobuf_unittest; |
||||
|
||||
|
||||
message TestMessage3 { |
||||
message NestedMessage { |
||||
// This enum's name is the same with the default outer class name of this |
||||
// proto file. It's used to test if the compiler can avoid this conflict |
||||
// correctly. |
||||
enum OuterClassNameTest3 { |
||||
DUMMY_VALUE = 1; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,50 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
// Author: Jacob Butcher (jbaum@google.com) |
||||
// |
||||
// Test file option java_string_check_utf8. |
||||
|
||||
package proto2_test_check_utf8; |
||||
|
||||
option java_outer_classname = "TestCheckUtf8"; |
||||
option java_string_check_utf8 = true; |
||||
|
||||
message StringWrapper { |
||||
required string req = 1; |
||||
optional string opt = 2; |
||||
repeated string rep = 3; |
||||
} |
||||
|
||||
message BytesWrapper { |
||||
required bytes req = 1; |
||||
optional bytes opt = 2; |
||||
repeated bytes rep = 3; |
||||
} |
@ -0,0 +1,51 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
// Author: Jacob Butcher (jbaum@google.com) |
||||
// |
||||
// Test file option java_string_check_utf8. |
||||
|
||||
package proto2_test_check_utf8_size; |
||||
|
||||
option java_outer_classname = "TestCheckUtf8Size"; |
||||
option java_string_check_utf8 = true; |
||||
option optimize_for = CODE_SIZE; |
||||
|
||||
message StringWrapperSize { |
||||
required string req = 1; |
||||
optional string opt = 2; |
||||
repeated string rep = 3; |
||||
} |
||||
|
||||
message BytesWrapperSize { |
||||
required bytes req = 1; |
||||
optional bytes opt = 2; |
||||
repeated bytes rep = 3; |
||||
} |
@ -0,0 +1,43 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
// Author: Feng Xiao (xiaofeng@google.com) |
||||
// |
||||
// Test that custom options defined in a proto file's dependencies are properly |
||||
// initialized. |
||||
|
||||
package protobuf_unittest; |
||||
|
||||
|
||||
import "google/protobuf/unittest_custom_options.proto"; |
||||
|
||||
message TestMessageWithCustomOptionsContainer { |
||||
optional TestMessageWithCustomOptions field = 1; |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,337 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: petar@google.com (Petar Petrov)
|
||||
|
||||
#include <Python.h> |
||||
#include <string> |
||||
|
||||
#include <google/protobuf/pyext/python_descriptor.h> |
||||
#include <google/protobuf/descriptor.pb.h> |
||||
|
||||
#define C(str) const_cast<char*>(str) |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace python { |
||||
|
||||
|
||||
static void CFieldDescriptorDealloc(CFieldDescriptor* self); |
||||
|
||||
static google::protobuf::DescriptorPool* g_descriptor_pool = NULL; |
||||
|
||||
static PyObject* CFieldDescriptor_GetFullName( |
||||
CFieldDescriptor* self, void *closure) { |
||||
Py_XINCREF(self->full_name); |
||||
return self->full_name; |
||||
} |
||||
|
||||
static PyObject* CFieldDescriptor_GetName( |
||||
CFieldDescriptor *self, void *closure) { |
||||
Py_XINCREF(self->name); |
||||
return self->name; |
||||
} |
||||
|
||||
static PyObject* CFieldDescriptor_GetCppType( |
||||
CFieldDescriptor *self, void *closure) { |
||||
Py_XINCREF(self->cpp_type); |
||||
return self->cpp_type; |
||||
} |
||||
|
||||
static PyObject* CFieldDescriptor_GetLabel( |
||||
CFieldDescriptor *self, void *closure) { |
||||
Py_XINCREF(self->label); |
||||
return self->label; |
||||
} |
||||
|
||||
static PyObject* CFieldDescriptor_GetID( |
||||
CFieldDescriptor *self, void *closure) { |
||||
Py_XINCREF(self->id); |
||||
return self->id; |
||||
} |
||||
|
||||
|
||||
static PyGetSetDef CFieldDescriptorGetters[] = { |
||||
{ C("full_name"), |
||||
(getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL}, |
||||
{ C("name"), |
||||
(getter)CFieldDescriptor_GetName, NULL, "last name", NULL}, |
||||
{ C("cpp_type"), |
||||
(getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL}, |
||||
{ C("label"), |
||||
(getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL}, |
||||
{ C("id"), |
||||
(getter)CFieldDescriptor_GetID, NULL, "ID", NULL}, |
||||
{NULL} |
||||
}; |
||||
|
||||
PyTypeObject CFieldDescriptor_Type = { |
||||
PyObject_HEAD_INIT(&PyType_Type) |
||||
0, |
||||
C("google.protobuf.internal." |
||||
"_net_proto2___python." |
||||
"CFieldDescriptor"), // tp_name
|
||||
sizeof(CFieldDescriptor), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor)CFieldDescriptorDealloc, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
0, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
0, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
C("A Field Descriptor"), // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
0, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
0, // tp_methods
|
||||
0, // tp_members
|
||||
CFieldDescriptorGetters, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
0, // tp_descr_set
|
||||
0, // tp_dictoffset
|
||||
0, // tp_init
|
||||
PyType_GenericAlloc, // tp_alloc
|
||||
PyType_GenericNew, // tp_new
|
||||
PyObject_Del, // tp_free
|
||||
}; |
||||
|
||||
static void CFieldDescriptorDealloc(CFieldDescriptor* self) { |
||||
Py_DECREF(self->full_name); |
||||
Py_DECREF(self->name); |
||||
Py_DECREF(self->cpp_type); |
||||
Py_DECREF(self->label); |
||||
Py_DECREF(self->id); |
||||
self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); |
||||
} |
||||
|
||||
typedef struct { |
||||
PyObject_HEAD |
||||
|
||||
const google::protobuf::DescriptorPool* pool; |
||||
} CDescriptorPool; |
||||
|
||||
static void CDescriptorPoolDealloc(CDescriptorPool* self); |
||||
|
||||
static PyObject* CDescriptorPool_NewCDescriptor( |
||||
const google::protobuf::FieldDescriptor* field_descriptor) { |
||||
CFieldDescriptor* cfield_descriptor = PyObject_New( |
||||
CFieldDescriptor, &CFieldDescriptor_Type); |
||||
if (cfield_descriptor == NULL) { |
||||
return NULL; |
||||
} |
||||
cfield_descriptor->descriptor = field_descriptor; |
||||
|
||||
cfield_descriptor->full_name = PyString_FromString( |
||||
field_descriptor->full_name().c_str()); |
||||
cfield_descriptor->name = PyString_FromString( |
||||
field_descriptor->name().c_str()); |
||||
cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type()); |
||||
cfield_descriptor->label = PyLong_FromLong(field_descriptor->label()); |
||||
cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor); |
||||
return reinterpret_cast<PyObject*>(cfield_descriptor); |
||||
} |
||||
|
||||
static PyObject* CDescriptorPool_FindFieldByName( |
||||
CDescriptorPool* self, PyObject* arg) { |
||||
const char* full_field_name = PyString_AsString(arg); |
||||
if (full_field_name == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
const google::protobuf::FieldDescriptor* field_descriptor = NULL; |
||||
|
||||
field_descriptor = self->pool->FindFieldByName(full_field_name); |
||||
|
||||
|
||||
if (field_descriptor == NULL) { |
||||
PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", |
||||
full_field_name); |
||||
return NULL; |
||||
} |
||||
|
||||
return CDescriptorPool_NewCDescriptor(field_descriptor); |
||||
} |
||||
|
||||
static PyObject* CDescriptorPool_FindExtensionByName( |
||||
CDescriptorPool* self, PyObject* arg) { |
||||
const char* full_field_name = PyString_AsString(arg); |
||||
if (full_field_name == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
const google::protobuf::FieldDescriptor* field_descriptor = |
||||
self->pool->FindExtensionByName(full_field_name); |
||||
if (field_descriptor == NULL) { |
||||
PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", |
||||
full_field_name); |
||||
return NULL; |
||||
} |
||||
|
||||
return CDescriptorPool_NewCDescriptor(field_descriptor); |
||||
} |
||||
|
||||
static PyMethodDef CDescriptorPoolMethods[] = { |
||||
{ C("FindFieldByName"), |
||||
(PyCFunction)CDescriptorPool_FindFieldByName, |
||||
METH_O, |
||||
C("Searches for a field descriptor by full name.") }, |
||||
{ C("FindExtensionByName"), |
||||
(PyCFunction)CDescriptorPool_FindExtensionByName, |
||||
METH_O, |
||||
C("Searches for extension descriptor by full name.") }, |
||||
{NULL} |
||||
}; |
||||
|
||||
PyTypeObject CDescriptorPool_Type = { |
||||
PyObject_HEAD_INIT(&PyType_Type) |
||||
0, |
||||
C("google.protobuf.internal." |
||||
"_net_proto2___python." |
||||
"CFieldDescriptor"), // tp_name
|
||||
sizeof(CDescriptorPool), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor)CDescriptorPoolDealloc, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
0, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
0, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
C("A Descriptor Pool"), // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
0, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
CDescriptorPoolMethods, // tp_methods
|
||||
0, // tp_members
|
||||
0, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
0, // tp_descr_set
|
||||
0, // tp_dictoffset
|
||||
0, // tp_init
|
||||
PyType_GenericAlloc, // tp_alloc
|
||||
PyType_GenericNew, // tp_new
|
||||
PyObject_Del, // tp_free
|
||||
}; |
||||
|
||||
static void CDescriptorPoolDealloc(CDescriptorPool* self) { |
||||
self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); |
||||
} |
||||
|
||||
google::protobuf::DescriptorPool* GetDescriptorPool() { |
||||
if (g_descriptor_pool == NULL) { |
||||
g_descriptor_pool = new google::protobuf::DescriptorPool( |
||||
google::protobuf::DescriptorPool::generated_pool()); |
||||
} |
||||
return g_descriptor_pool; |
||||
} |
||||
|
||||
PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) { |
||||
CDescriptorPool* cdescriptor_pool = PyObject_New( |
||||
CDescriptorPool, &CDescriptorPool_Type); |
||||
if (cdescriptor_pool == NULL) { |
||||
return NULL; |
||||
} |
||||
cdescriptor_pool->pool = GetDescriptorPool(); |
||||
return reinterpret_cast<PyObject*>(cdescriptor_pool); |
||||
} |
||||
|
||||
PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) { |
||||
char* message_type; |
||||
Py_ssize_t message_len; |
||||
|
||||
if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) { |
||||
return NULL; |
||||
} |
||||
|
||||
google::protobuf::FileDescriptorProto file_proto; |
||||
if (!file_proto.ParseFromArray(message_type, message_len)) { |
||||
PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); |
||||
return NULL; |
||||
} |
||||
|
||||
if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName( |
||||
file_proto.name()) != NULL) { |
||||
Py_RETURN_NONE; |
||||
} |
||||
|
||||
const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->BuildFile( |
||||
file_proto); |
||||
if (descriptor == NULL) { |
||||
PyErr_SetString(PyExc_TypeError, |
||||
"Couldn't build proto file into descriptor pool!"); |
||||
return NULL; |
||||
} |
||||
|
||||
Py_RETURN_NONE; |
||||
} |
||||
|
||||
bool InitDescriptor() { |
||||
CFieldDescriptor_Type.tp_new = PyType_GenericNew; |
||||
if (PyType_Ready(&CFieldDescriptor_Type) < 0) |
||||
return false; |
||||
|
||||
CDescriptorPool_Type.tp_new = PyType_GenericNew; |
||||
if (PyType_Ready(&CDescriptorPool_Type) < 0) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
} // namespace python
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue