Integrated internal changes from Google
This commit is contained in:
parent
e28286fa05
commit
5a76e633ea
@ -1,8 +1,11 @@
|
||||
|
||||
import com.google.protobuf.conformance.Conformance;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import com.google.protobuf.util.JsonFormat.TypeRegistry;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.conformance.Conformance;
|
||||
import com.google.protobuf.util.JsonFormat.TypeRegistry;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
class ConformanceJava {
|
||||
private int testCount = 0;
|
||||
@ -47,13 +50,182 @@ class ConformanceJava {
|
||||
writeToStdout(buf);
|
||||
}
|
||||
|
||||
private enum BinaryDecoder {
|
||||
BYTE_STRING_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
return Conformance.TestAllTypes.parseFrom(bytes);
|
||||
}
|
||||
},
|
||||
BYTE_ARRAY_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
return Conformance.TestAllTypes.parseFrom(bytes.toByteArray());
|
||||
}
|
||||
},
|
||||
ARRAY_BYTE_BUFFER_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(bytes.size());
|
||||
bytes.copyTo(buffer);
|
||||
buffer.flip();
|
||||
try {
|
||||
return Conformance.TestAllTypes.parseFrom(CodedInputStream.newInstance(buffer));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"ByteString based ByteBuffer should not throw IOException.", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
READONLY_ARRAY_BYTE_BUFFER_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
return Conformance.TestAllTypes.parseFrom(
|
||||
CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"ByteString based ByteBuffer should not throw IOException.", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
DIRECT_BYTE_BUFFER_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
|
||||
bytes.copyTo(buffer);
|
||||
buffer.flip();
|
||||
try {
|
||||
return Conformance.TestAllTypes.parseFrom(CodedInputStream.newInstance(buffer));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"ByteString based ByteBuffer should not throw IOException.", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
READONLY_DIRECT_BYTE_BUFFER_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
|
||||
bytes.copyTo(buffer);
|
||||
buffer.flip();
|
||||
try {
|
||||
return Conformance.TestAllTypes.parseFrom(
|
||||
CodedInputStream.newInstance(buffer.asReadOnlyBuffer()));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"ByteString based ByteBuffer should not throw IOException.", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
INPUT_STREAM_DECODER() {
|
||||
@Override
|
||||
public Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
return Conformance.TestAllTypes.parseFrom(bytes.newInput());
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"ByteString based InputStream should not throw IOException.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Conformance.TestAllTypes parse(ByteString bytes)
|
||||
throws InvalidProtocolBufferException;
|
||||
}
|
||||
|
||||
private Conformance.TestAllTypes parseBinary(ByteString bytes)
|
||||
throws InvalidProtocolBufferException {
|
||||
Conformance.TestAllTypes[] messages =
|
||||
new Conformance.TestAllTypes[BinaryDecoder.values().length];
|
||||
InvalidProtocolBufferException[] exceptions =
|
||||
new InvalidProtocolBufferException[BinaryDecoder.values().length];
|
||||
|
||||
boolean hasMessage = false;
|
||||
boolean hasException = false;
|
||||
for (int i = 0; i < BinaryDecoder.values().length; ++i) {
|
||||
try {
|
||||
messages[i] = BinaryDecoder.values()[i].parse(bytes);
|
||||
hasMessage = true;
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
exceptions[i] = e;
|
||||
hasException = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMessage && hasException) {
|
||||
StringBuilder sb =
|
||||
new StringBuilder("Binary decoders disagreed on whether the payload was valid.\n");
|
||||
for (int i = 0; i < BinaryDecoder.values().length; ++i) {
|
||||
sb.append(BinaryDecoder.values()[i].name());
|
||||
if (messages[i] != null) {
|
||||
sb.append(" accepted the payload.\n");
|
||||
} else {
|
||||
sb.append(" rejected the payload.\n");
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(sb.toString());
|
||||
}
|
||||
|
||||
if (hasException) {
|
||||
// We do not check if exceptions are equal. Different implementations may return different
|
||||
// exception messages. Throw an arbitrary one out instead.
|
||||
throw exceptions[0];
|
||||
}
|
||||
|
||||
// Fast path comparing all the messages with the first message, assuming equality being
|
||||
// symmetric and transitive.
|
||||
boolean allEqual = true;
|
||||
for (int i = 1; i < messages.length; ++i) {
|
||||
if (!messages[0].equals(messages[i])) {
|
||||
allEqual = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Slow path: compare and find out all unequal pairs.
|
||||
if (!allEqual) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < messages.length - 1; ++i) {
|
||||
for (int j = i + 1; j < messages.length; ++j) {
|
||||
if (!messages[i].equals(messages[j])) {
|
||||
sb.append(BinaryDecoder.values()[i].name())
|
||||
.append(" and ")
|
||||
.append(BinaryDecoder.values()[j].name())
|
||||
.append(" parsed the payload differently.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(sb.toString());
|
||||
}
|
||||
|
||||
return messages[0];
|
||||
}
|
||||
|
||||
private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
|
||||
Conformance.TestAllTypes testMessage;
|
||||
|
||||
switch (request.getPayloadCase()) {
|
||||
case PROTOBUF_PAYLOAD: {
|
||||
try {
|
||||
testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
|
||||
testMessage = parseBinary(request.getProtobufPayload());
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
|
||||
}
|
||||
|
@ -685,7 +685,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||
R"({
|
||||
"fieldname1": 1,
|
||||
"fieldName2": 2,
|
||||
"fieldName3": 3,
|
||||
"FieldName3": 3,
|
||||
"fieldName4": 4
|
||||
})",
|
||||
R"(
|
||||
@ -725,12 +725,12 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||
RunValidJsonTest(
|
||||
"FieldNameWithDoubleUnderscores", RECOMMENDED,
|
||||
R"({
|
||||
"fieldName13": 13,
|
||||
"fieldName14": 14,
|
||||
"FieldName13": 13,
|
||||
"FieldName14": 14,
|
||||
"fieldName15": 15,
|
||||
"fieldName16": 16,
|
||||
"fieldName17": 17,
|
||||
"fieldName18": 18
|
||||
"FieldName18": 18
|
||||
})",
|
||||
R"(
|
||||
__field_name13: 13
|
||||
@ -873,21 +873,19 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||
"optionalNestedMessage": {a: 1},
|
||||
"optional_nested_message": {}
|
||||
})");
|
||||
// NOTE: The spec for JSON support is still being sorted out, these may not
|
||||
// all be correct.
|
||||
// Serializers should use lowerCamelCase by default.
|
||||
RunValidJsonTestWithValidator(
|
||||
"FieldNameInLowerCamelCase", REQUIRED,
|
||||
R"({
|
||||
"fieldname1": 1,
|
||||
"fieldName2": 2,
|
||||
"fieldName3": 3,
|
||||
"FieldName3": 3,
|
||||
"fieldName4": 4
|
||||
})",
|
||||
[](const Json::Value& value) {
|
||||
return value.isMember("fieldname1") &&
|
||||
value.isMember("fieldName2") &&
|
||||
value.isMember("fieldName3") &&
|
||||
value.isMember("FieldName3") &&
|
||||
value.isMember("fieldName4");
|
||||
});
|
||||
RunValidJsonTestWithValidator(
|
||||
@ -921,20 +919,20 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||
RunValidJsonTestWithValidator(
|
||||
"FieldNameWithDoubleUnderscores", RECOMMENDED,
|
||||
R"({
|
||||
"fieldName13": 13,
|
||||
"fieldName14": 14,
|
||||
"FieldName13": 13,
|
||||
"FieldName14": 14,
|
||||
"fieldName15": 15,
|
||||
"fieldName16": 16,
|
||||
"fieldName17": 17,
|
||||
"fieldName18": 18
|
||||
"FieldName18": 18
|
||||
})",
|
||||
[](const Json::Value& value) {
|
||||
return value.isMember("fieldName13") &&
|
||||
value.isMember("fieldName14") &&
|
||||
return value.isMember("FieldName13") &&
|
||||
value.isMember("FieldName14") &&
|
||||
value.isMember("fieldName15") &&
|
||||
value.isMember("fieldName16") &&
|
||||
value.isMember("fieldName17") &&
|
||||
value.isMember("fieldName18");
|
||||
value.isMember("FieldName18");
|
||||
});
|
||||
|
||||
// Integer fields.
|
||||
|
@ -17,9 +17,6 @@ Recommended.JsonInput.FieldNameDuplicate
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
|
||||
Recommended.JsonInput.FieldNameNotQuoted
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
|
||||
Recommended.JsonInput.MapFieldValueIsNull
|
||||
Recommended.JsonInput.RepeatedFieldMessageElementIsNull
|
||||
Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
|
||||
@ -35,10 +32,6 @@ Recommended.JsonInput.TrailingCommaInAnObject
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
|
||||
Required.JsonInput.DoubleFieldTooSmall
|
||||
Required.JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
|
||||
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
|
@ -20,9 +20,6 @@ Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||
Recommended.JsonInput.FieldMaskInvalidCharacter
|
||||
Recommended.JsonInput.FieldNameDuplicate
|
||||
Recommended.JsonInput.FieldNameNotQuoted
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
|
||||
Recommended.JsonInput.FloatFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNanNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||
@ -35,15 +32,15 @@ Recommended.JsonInput.StringFieldSingleQuoteValue
|
||||
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
|
||||
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
|
||||
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
|
||||
Recommended.JsonInput.StringFieldUppercaseEscapeLetter
|
||||
Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
|
||||
Required.JsonInput.EnumFieldNotQuoted
|
||||
Required.JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
|
||||
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldLeadingZero
|
||||
Required.JsonInput.Int32FieldNegativeWithLeadingZero
|
||||
Required.JsonInput.Int32FieldPlusSign
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
|
||||
Required.JsonInput.StringFieldNotAString
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
|
@ -1,18 +1,12 @@
|
||||
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNanNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
|
||||
Recommended.JsonInput.FloatFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNanNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||
Required.JsonInput.BytesFieldInvalidBase64Characters
|
||||
Required.JsonInput.DoubleFieldTooSmall
|
||||
Required.JsonInput.EnumFieldUnknownValue.Validator
|
||||
Required.JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
|
||||
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldTooLarge
|
||||
Required.JsonInput.FloatFieldTooSmall
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
|
||||
|
@ -10,18 +10,12 @@
|
||||
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNanNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
|
||||
Recommended.JsonInput.FloatFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNanNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||
Required.JsonInput.BytesFieldInvalidBase64Characters
|
||||
Required.JsonInput.DoubleFieldTooSmall
|
||||
Required.JsonInput.EnumFieldUnknownValue.Validator
|
||||
Required.JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
|
||||
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldTooLarge
|
||||
Required.JsonInput.FloatFieldTooSmall
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
|
||||
|
@ -232,7 +232,7 @@ public abstract class AbstractParser<MessageType extends MessageLite>
|
||||
}
|
||||
size = CodedInputStream.readRawVarint32(firstByte, input);
|
||||
} catch (IOException e) {
|
||||
throw new InvalidProtocolBufferException(e.getMessage());
|
||||
throw new InvalidProtocolBufferException(e);
|
||||
}
|
||||
InputStream limitedInput = new LimitedInputStream(input, size);
|
||||
return parsePartialFrom(limitedInput, extensionRegistry);
|
||||
|
@ -51,14 +51,12 @@ import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Immutable sequence of bytes. Substring is supported by sharing the reference
|
||||
* to the immutable underlying bytes. Concatenation is likewise supported
|
||||
* without copying (long strings) by building a tree of pieces in
|
||||
* {@link RopeByteString}.
|
||||
* <p>
|
||||
* Like {@link String}, the contents of a {@link ByteString} can never be
|
||||
* observed to change, not even in the presence of a data race or incorrect
|
||||
* API usage in the client code.
|
||||
* Immutable sequence of bytes. Substring is supported by sharing the reference to the immutable
|
||||
* underlying bytes. Concatenation is likewise supported without copying (long strings) by building
|
||||
* a tree of pieces in {@link RopeByteString}.
|
||||
*
|
||||
* <p>Like {@link String}, the contents of a {@link ByteString} can never be observed to change, not
|
||||
* even in the presence of a data race or incorrect API usage in the client code.
|
||||
*
|
||||
* @author crazybob@google.com Bob Lee
|
||||
* @author kenton@google.com Kenton Varda
|
||||
@ -565,7 +563,9 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
// Create a balanced concatenation of the next "length" elements from the
|
||||
// iterable.
|
||||
private static ByteString balancedConcat(Iterator<ByteString> iterator, int length) {
|
||||
assert length >= 1;
|
||||
if (length < 1) {
|
||||
throw new IllegalArgumentException(String.format("length (%s) must be >= 1", length));
|
||||
}
|
||||
ByteString result;
|
||||
if (length == 1) {
|
||||
result = iterator.next();
|
||||
|
@ -2123,7 +2123,7 @@ public final class Descriptors {
|
||||
// Can't happen, because addPackage() only fails when the name
|
||||
// conflicts with a non-package, but we have not yet added any
|
||||
// non-packages at this point.
|
||||
assert false;
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(builder.buildPartial());
|
||||
} catch (IOException e) {
|
||||
throw new InvalidProtocolBufferException(e.getMessage())
|
||||
throw new InvalidProtocolBufferException(e)
|
||||
.setUnfinishedMessage(builder.buildPartial());
|
||||
}
|
||||
return builder.buildPartial();
|
||||
|
@ -32,7 +32,6 @@ package com.google.protobuf;
|
||||
|
||||
import com.google.protobuf.Descriptors.Descriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -105,9 +105,9 @@ public class ExtensionRegistryLite {
|
||||
|
||||
/**
|
||||
* Construct a new, empty instance.
|
||||
*
|
||||
* <p>
|
||||
* This may be an {@code ExtensionRegistry} if the full (non-Lite) proto libraries are available.
|
||||
*
|
||||
* <p>This may be an {@code ExtensionRegistry} if the full (non-Lite) proto libraries are
|
||||
* available.
|
||||
*/
|
||||
public static ExtensionRegistryLite newInstance() {
|
||||
return ExtensionRegistryFactory.create();
|
||||
@ -121,6 +121,7 @@ public class ExtensionRegistryLite {
|
||||
return ExtensionRegistryFactory.createEmpty();
|
||||
}
|
||||
|
||||
|
||||
/** Returns an unmodifiable view of the registry. */
|
||||
public ExtensionRegistryLite getUnmodifiable() {
|
||||
return new ExtensionRegistryLite(this);
|
||||
|
@ -39,7 +39,6 @@ import com.google.protobuf.Internal.IntList;
|
||||
import com.google.protobuf.Internal.LongList;
|
||||
import com.google.protobuf.Internal.ProtobufList;
|
||||
import com.google.protobuf.WireFormat.FieldType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
@ -479,7 +478,6 @@ public abstract class GeneratedMessageLite<
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int tag) throws IOException {
|
||||
int wireType = WireFormat.getTagWireType(tag);
|
||||
int fieldNumber = WireFormat.getTagFieldNumber(tag);
|
||||
|
||||
// TODO(dweis): How much bytecode would be saved by not requiring the generated code to
|
||||
@ -487,6 +485,17 @@ public abstract class GeneratedMessageLite<
|
||||
GeneratedExtension<MessageType, ?> extension = extensionRegistry.findLiteExtensionByNumber(
|
||||
defaultInstance, fieldNumber);
|
||||
|
||||
return parseExtension(input, extensionRegistry, extension, tag, fieldNumber);
|
||||
}
|
||||
|
||||
private boolean parseExtension(
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
GeneratedExtension<?, ?> extension,
|
||||
int tag,
|
||||
int fieldNumber)
|
||||
throws IOException {
|
||||
int wireType = WireFormat.getTagWireType(tag);
|
||||
boolean unknown = false;
|
||||
boolean packed = false;
|
||||
if (extension == null) {
|
||||
@ -508,7 +517,7 @@ public abstract class GeneratedMessageLite<
|
||||
if (unknown) { // Unknown field or wrong wire type. Skip.
|
||||
return parseUnknownField(tag, input);
|
||||
}
|
||||
|
||||
|
||||
if (packed) {
|
||||
int length = input.readRawVarint32();
|
||||
int limit = input.pushLimit(length);
|
||||
@ -587,9 +596,147 @@ public abstract class GeneratedMessageLite<
|
||||
extension.singularToFieldSetType(value));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an unknown field or an extension. For use by generated code only.
|
||||
*
|
||||
* <p>For use by generated code only.
|
||||
*
|
||||
* @return {@code true} unless the tag is an end-group tag.
|
||||
*/
|
||||
protected <MessageType extends MessageLite> boolean parseUnknownFieldAsMessageSet(
|
||||
MessageType defaultInstance,
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int tag)
|
||||
throws IOException {
|
||||
|
||||
if (tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
|
||||
mergeMessageSetExtensionFromCodedStream(defaultInstance, input, extensionRegistry);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO(dweis): Do we really want to support non message set wire format in message sets?
|
||||
// Full runtime does... So we do for now.
|
||||
int wireType = WireFormat.getTagWireType(tag);
|
||||
if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
|
||||
return parseUnknownField(defaultInstance, input, extensionRegistry, tag);
|
||||
} else {
|
||||
// TODO(dweis): Should we throw on invalid input? Full runtime does not...
|
||||
return input.skipField(tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the message set from the input stream; requires message set wire format.
|
||||
*
|
||||
* @param defaultInstance the default instance of the containing message we are parsing in
|
||||
* @param input the stream to parse from
|
||||
* @param extensionRegistry the registry to use when parsing
|
||||
*/
|
||||
private <MessageType extends MessageLite> void mergeMessageSetExtensionFromCodedStream(
|
||||
MessageType defaultInstance,
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
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"
|
||||
GeneratedExtension<?, ?> 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) {
|
||||
extension = extensionRegistry.findLiteExtensionByNumber(defaultInstance, typeId);
|
||||
}
|
||||
|
||||
} else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
|
||||
if (typeId != 0) {
|
||||
if (extension != null) {
|
||||
// We already know the type, so we can parse directly from the
|
||||
// input with no copying. Hooray!
|
||||
eagerlyMergeMessageSetExtension(input, extension, extensionRegistry, typeId);
|
||||
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, extensionRegistry, extension);
|
||||
} else { // We don't know how to parse this. Ignore it.
|
||||
if (rawBytes != null) {
|
||||
mergeLengthDelimitedField(typeId, rawBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void eagerlyMergeMessageSetExtension(
|
||||
CodedInputStream input,
|
||||
GeneratedExtension<?, ?> extension,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int typeId)
|
||||
throws IOException {
|
||||
int fieldNumber = typeId;
|
||||
int tag = WireFormat.makeTag(typeId, WireFormat.WIRETYPE_LENGTH_DELIMITED);
|
||||
parseExtension(input, extensionRegistry, extension, tag, fieldNumber);
|
||||
}
|
||||
|
||||
private void mergeMessageSetExtensionFromBytes(
|
||||
ByteString rawBytes,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
GeneratedExtension<?, ?> extension)
|
||||
throws IOException {
|
||||
MessageLite.Builder subBuilder = null;
|
||||
MessageLite existingValue = (MessageLite) extensions.getField(extension.descriptor);
|
||||
if (existingValue != null) {
|
||||
subBuilder = existingValue.toBuilder();
|
||||
}
|
||||
if (subBuilder == null) {
|
||||
subBuilder = extension.getMessageDefaultInstance().newBuilderForType();
|
||||
}
|
||||
rawBytes.newCodedInput().readMessage(subBuilder, extensionRegistry);
|
||||
MessageLite value = subBuilder.build();
|
||||
|
||||
extensions.setField(extension.descriptor, extension.singularToFieldSetType(value));
|
||||
}
|
||||
|
||||
private void verifyExtensionContainingType(
|
||||
final GeneratedExtension<MessageType, ?> extension) {
|
||||
@ -807,14 +954,6 @@ public abstract class GeneratedMessageLite<
|
||||
return instance.getExtension(extension, index);
|
||||
}
|
||||
|
||||
// This is implemented here only to work around an apparent bug in the
|
||||
// Java compiler and/or build system. See bug #1898463. The mere presence
|
||||
// of this dummy clone() implementation makes it go away.
|
||||
@Override
|
||||
public BuilderType clone() {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
/** Set the value of an extension. */
|
||||
public final <Type> BuilderType setExtension(
|
||||
final ExtensionLite<MessageType, Type> extension,
|
||||
|
@ -36,6 +36,16 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
import com.google.protobuf.Descriptors.FileDescriptor;
|
||||
import com.google.protobuf.Descriptors.OneofDescriptor;
|
||||
// In opensource protobuf, we have versioned this GeneratedMessageV3 class to GeneratedMessageV3V3 and
|
||||
// in the future may have GeneratedMessageV3V4 etc. This allows us to change some aspects of this
|
||||
// class without breaking binary compatibility with old generated code that still subclasses
|
||||
// the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to
|
||||
// interoperate (e.g., a GeneratedMessageV3V3 object has a message extension field whose class
|
||||
// type is GeneratedMessageV3V4), these classes still share a common parent class AbstarctMessage
|
||||
// and are using the same GeneratedMessage.GeneratedExtension class for extension definitions.
|
||||
// Since this class becomes GeneratedMessageV3V? in opensource, we have to add an import here
|
||||
// to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in
|
||||
// this file is also excluded from opensource to avoid conflict.
|
||||
import com.google.protobuf.GeneratedMessage.GeneratedExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -1207,14 +1217,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
return super.clear();
|
||||
}
|
||||
|
||||
// This is implemented here only to work around an apparent bug in the
|
||||
// Java compiler and/or build system. See bug #1898463. The mere presence
|
||||
// of this clone() implementation makes it go away.
|
||||
@Override
|
||||
public BuilderType clone() {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
private void ensureExtensionsIsMutable() {
|
||||
if (extensions.isImmutable()) {
|
||||
extensions = extensions.clone();
|
||||
@ -1610,6 +1612,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
FieldDescriptor getDescriptor();
|
||||
}
|
||||
|
||||
|
||||
// =================================================================
|
||||
|
||||
/** Calls Class.getMethod and throws a RuntimeException if it fails. */
|
||||
@ -1705,11 +1708,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
private boolean isMapFieldEnabled(FieldDescriptor field) {
|
||||
boolean result = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the field accessors are initialized. This method is thread-safe.
|
||||
*
|
||||
@ -1733,7 +1731,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
}
|
||||
if (field.isRepeated()) {
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
if (field.isMapField() && isMapFieldEnabled(field)) {
|
||||
if (field.isMapField()) {
|
||||
fields[i] = new MapFieldAccessor(
|
||||
field, camelCaseNames[i], messageClass, builderClass);
|
||||
} else {
|
||||
|
@ -284,29 +284,8 @@ public class LazyFieldLite {
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point we have two fully parsed messages. We can't merge directly from one to the
|
||||
// other because only generated builder code contains methods to mergeFrom another parsed
|
||||
// message. We have to serialize one instance and then merge the bytes into the other. This may
|
||||
// drop extensions from one of the messages if one of the values had an extension set on it
|
||||
// directly.
|
||||
//
|
||||
// To mitigate this we prefer serializing a message that has an extension registry, and
|
||||
// therefore a chance that all extensions set on it are in that registry.
|
||||
//
|
||||
// NOTE: The check for other.extensionRegistry not being null must come first because at this
|
||||
// point in time if other.extensionRegistry is not null then this.extensionRegistry will not be
|
||||
// null either.
|
||||
if (other.extensionRegistry != null) {
|
||||
setValue(mergeValueAndBytes(this.value, other.toByteString(), other.extensionRegistry));
|
||||
return;
|
||||
} else if (this.extensionRegistry != null) {
|
||||
setValue(mergeValueAndBytes(other.value, this.toByteString(), this.extensionRegistry));
|
||||
return;
|
||||
} else {
|
||||
// All extensions from the other message will be dropped because we have no registry.
|
||||
setValue(mergeValueAndBytes(this.value, other.toByteString(), EMPTY_REGISTRY));
|
||||
return;
|
||||
}
|
||||
// At this point we have two fully parsed messages.
|
||||
setValue(this.value.toBuilder().mergeFrom(other.value).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,7 +109,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (IOException e) {
|
||||
throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(this);
|
||||
throw new InvalidProtocolBufferException(e).setUnfinishedMessage(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ final class MessageLiteToString {
|
||||
// Try to reflectively get the value and toString() the field as if it were repeated. This
|
||||
// only works if the method names have not be proguarded out or renamed.
|
||||
Method listMethod = nameToNoArgMethod.get("get" + suffix);
|
||||
if (listMethod != null) {
|
||||
if (listMethod != null && listMethod.getReturnType().equals(List.class)) {
|
||||
printField(
|
||||
buffer,
|
||||
indent,
|
||||
@ -115,7 +115,7 @@ final class MessageLiteToString {
|
||||
// Heuristic to skip bytes based accessors for string fields.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
String camelCase = suffix.substring(0, 1).toLowerCase() + suffix.substring(1);
|
||||
|
||||
// Try to reflectively get the value and toString() the field as if it were optional. This
|
||||
|
@ -1022,7 +1022,7 @@ public final class UnknownFieldSet implements MessageLite {
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(builder.buildPartial());
|
||||
} catch (IOException e) {
|
||||
throw new InvalidProtocolBufferException(e.getMessage())
|
||||
throw new InvalidProtocolBufferException(e)
|
||||
.setUnfinishedMessage(builder.buildPartial());
|
||||
}
|
||||
return builder.buildPartial();
|
||||
|
@ -175,6 +175,41 @@ public final class UnknownFieldSetLite {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the set and writes it to {@code output} using {@code MessageSet} wire format.
|
||||
*
|
||||
* <p>For use by generated code only.
|
||||
*/
|
||||
public void writeAsMessageSetTo(CodedOutputStream output) throws IOException {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
|
||||
output.writeRawMessageSetExtension(fieldNumber, (ByteString) objects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of bytes required to encode this field, including field
|
||||
* number, using {@code MessageSet} wire format.
|
||||
*/
|
||||
public int getSerializedSizeAsMessageSet() {
|
||||
int size = memoizedSerializedSize;
|
||||
if (size != -1) {
|
||||
return size;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int tag = tags[i];
|
||||
int fieldNumber = WireFormat.getTagFieldNumber(tag);
|
||||
size += CodedOutputStream.computeRawMessageSetExtensionSize(
|
||||
fieldNumber, (ByteString) objects[i]);
|
||||
}
|
||||
|
||||
memoizedSerializedSize = size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of bytes required to encode this set.
|
||||
*
|
||||
@ -268,7 +303,8 @@ public final class UnknownFieldSetLite {
|
||||
}
|
||||
}
|
||||
|
||||
private void storeField(int tag, Object value) {
|
||||
// Package private for unsafe experimental runtime.
|
||||
void storeField(int tag, Object value) {
|
||||
ensureCapacity();
|
||||
|
||||
tags[count] = tag;
|
||||
|
@ -31,7 +31,6 @@
|
||||
package com.google.protobuf;
|
||||
|
||||
import static protobuf_unittest.UnittestProto.optionalInt32Extension;
|
||||
import static protobuf_unittest.UnittestProto.optionalInt64Extension;
|
||||
|
||||
import protobuf_unittest.UnittestProto.TestAllExtensions;
|
||||
import protobuf_unittest.UnittestProto.TestAllTypes;
|
||||
@ -219,29 +218,6 @@ public class LazyFieldLiteTest extends TestCase {
|
||||
assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance()));
|
||||
}
|
||||
|
||||
public void testMergeMightLoseExtensions() throws Exception {
|
||||
// Test that we don't know about the extensions when parsing.
|
||||
TestAllExtensions message1 =
|
||||
TestAllExtensions.newBuilder().setExtension(optionalInt32Extension, 1).build();
|
||||
TestAllExtensions message2 =
|
||||
TestAllExtensions.newBuilder().setExtension(optionalInt64Extension, 2L).build();
|
||||
|
||||
LazyFieldLite field = LazyFieldLite.fromValue(message1);
|
||||
field.merge(LazyFieldLite.fromValue(message2));
|
||||
|
||||
// We lose the extensions from message 2 because we have to serialize it and then parse it
|
||||
// again, using the empty registry this time.
|
||||
TestAllExtensions value =
|
||||
(TestAllExtensions) field.getValue(TestAllExtensions.getDefaultInstance());
|
||||
assertTrue(value.hasExtension(optionalInt32Extension));
|
||||
assertEquals(Integer.valueOf(1), value.getExtension(optionalInt32Extension));
|
||||
assertFalse(value.hasExtension(optionalInt64Extension));
|
||||
|
||||
// The field is still there, it is just unknown.
|
||||
assertTrue(value.getUnknownFields()
|
||||
.hasField(optionalInt64Extension.getDescriptor().getNumber()));
|
||||
}
|
||||
|
||||
|
||||
// Help methods.
|
||||
|
||||
|
@ -101,6 +101,19 @@ public class LazyMessageLiteTest extends TestCase {
|
||||
assertEquals(119, outer.getRepeatedInner(0).getNum());
|
||||
assertEquals(122, outer.getRepeatedInner(1).getNum());
|
||||
}
|
||||
|
||||
public void testRepeatedMutability() throws Exception {
|
||||
LazyMessageLite outer = LazyMessageLite.newBuilder()
|
||||
.addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119))
|
||||
.addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122))
|
||||
.build();
|
||||
|
||||
outer = LazyMessageLite.parseFrom(outer.toByteArray());
|
||||
try {
|
||||
outer.getRepeatedInnerList().set(1, null);
|
||||
fail();
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testAddAll() {
|
||||
ArrayList<LazyInnerMessageLite> inners = new ArrayList<LazyInnerMessageLite>();
|
||||
|
@ -45,6 +45,7 @@ import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase;
|
||||
import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup;
|
||||
import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup;
|
||||
import com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder;
|
||||
import com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite;
|
||||
import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
|
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
|
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
|
||||
@ -1424,6 +1425,12 @@ public class LiteTest extends TestCase {
|
||||
assertToStringEquals("", TestAllTypesLite.getDefaultInstance());
|
||||
}
|
||||
|
||||
public void testToStringScalarFieldsSuffixedWithList() throws Exception {
|
||||
assertToStringEquals("deceptively_named_list: 7", TestAllTypesLite.newBuilder()
|
||||
.setDeceptivelyNamedList(7)
|
||||
.build());
|
||||
}
|
||||
|
||||
public void testToStringPrimitives() throws Exception {
|
||||
TestAllTypesLite proto = TestAllTypesLite.newBuilder()
|
||||
.setOptionalInt32(1)
|
||||
@ -2235,6 +2242,25 @@ public class LiteTest extends TestCase {
|
||||
assertFalse(other.equals(mine));
|
||||
}
|
||||
|
||||
public void testHugeFieldNumbers() throws InvalidProtocolBufferException {
|
||||
TestHugeFieldNumbersLite message =
|
||||
TestHugeFieldNumbersLite.newBuilder()
|
||||
.setOptionalInt32(1)
|
||||
.addRepeatedInt32(2)
|
||||
.setOptionalEnum(ForeignEnumLite.FOREIGN_LITE_FOO)
|
||||
.setOptionalString("xyz")
|
||||
.setOptionalMessage(ForeignMessageLite.newBuilder().setC(3).build())
|
||||
.build();
|
||||
|
||||
TestHugeFieldNumbersLite parsedMessage =
|
||||
TestHugeFieldNumbersLite.parseFrom(message.toByteArray());
|
||||
assertEquals(1, parsedMessage.getOptionalInt32());
|
||||
assertEquals(2, parsedMessage.getRepeatedInt32(0));
|
||||
assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, parsedMessage.getOptionalEnum());
|
||||
assertEquals("xyz", parsedMessage.getOptionalString());
|
||||
assertEquals(3, parsedMessage.getOptionalMessage().getC());
|
||||
}
|
||||
|
||||
private void assertEqualsAndHashCodeAreFalse(Object o1, Object o2) {
|
||||
assertFalse(o1.equals(o2));
|
||||
assertFalse(o1.hashCode() == o2.hashCode());
|
||||
|
@ -501,7 +501,6 @@ public final class MapForProto2LiteTest extends TestCase {
|
||||
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
|
||||
}
|
||||
|
||||
|
||||
public void testIterationOrder() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValues(builder);
|
||||
|
@ -58,26 +58,26 @@ public class MapForProto2Test extends TestCase {
|
||||
builder.getMutableInt32ToInt32Field().put(1, 11);
|
||||
builder.getMutableInt32ToInt32Field().put(2, 22);
|
||||
builder.getMutableInt32ToInt32Field().put(3, 33);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToStringField().put(1, "11");
|
||||
builder.getMutableInt32ToStringField().put(2, "22");
|
||||
builder.getMutableInt32ToStringField().put(3, "33");
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("11"));
|
||||
builder.getMutableInt32ToBytesField().put(2, TestUtil.toBytes("22"));
|
||||
builder.getMutableInt32ToBytesField().put(3, TestUtil.toBytes("33"));
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.FOO);
|
||||
builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.BAR);
|
||||
builder.getMutableInt32ToEnumField().put(3, TestMap.EnumValue.BAZ);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
1, MessageValue.newBuilder().setValue(11).build());
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
2, MessageValue.newBuilder().setValue(22).build());
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
3, MessageValue.newBuilder().setValue(33).build());
|
||||
|
||||
//
|
||||
builder.getMutableStringToInt32Field().put("1", 11);
|
||||
builder.getMutableStringToInt32Field().put("2", 22);
|
||||
builder.getMutableStringToInt32Field().put("3", 33);
|
||||
@ -120,6 +120,7 @@ public class MapForProto2Test extends TestCase {
|
||||
setMapValuesUsingAccessors(usingAccessorsBuilder);
|
||||
TestMap usingAccessors = usingAccessorsBuilder.build();
|
||||
assertMapValuesSet(usingAccessors);
|
||||
|
||||
assertEquals(usingAccessors, usingMutableMap);
|
||||
}
|
||||
|
||||
@ -169,25 +170,25 @@ public class MapForProto2Test extends TestCase {
|
||||
builder.getMutableInt32ToInt32Field().put(1, 111);
|
||||
builder.getMutableInt32ToInt32Field().remove(2);
|
||||
builder.getMutableInt32ToInt32Field().put(4, 44);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToStringField().put(1, "111");
|
||||
builder.getMutableInt32ToStringField().remove(2);
|
||||
builder.getMutableInt32ToStringField().put(4, "44");
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("111"));
|
||||
builder.getMutableInt32ToBytesField().remove(2);
|
||||
builder.getMutableInt32ToBytesField().put(4, TestUtil.toBytes("44"));
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.BAR);
|
||||
builder.getMutableInt32ToEnumField().remove(2);
|
||||
builder.getMutableInt32ToEnumField().put(4, TestMap.EnumValue.QUX);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
1, MessageValue.newBuilder().setValue(111).build());
|
||||
builder.getMutableInt32ToMessageField().remove(2);
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
4, MessageValue.newBuilder().setValue(44).build());
|
||||
|
||||
//
|
||||
builder.getMutableStringToInt32Field().put("1", 111);
|
||||
builder.getMutableStringToInt32Field().remove("2");
|
||||
builder.getMutableStringToInt32Field().put("4", 44);
|
||||
@ -230,8 +231,9 @@ public class MapForProto2Test extends TestCase {
|
||||
setMapValuesUsingAccessors(usingAccessorsBuilder);
|
||||
TestMap usingAccessors = usingAccessorsBuilder.build();
|
||||
assertMapValuesSet(usingAccessors);
|
||||
assertEquals(usingAccessors, usingMutableMap);
|
||||
|
||||
assertEquals(usingAccessors, usingMutableMap);
|
||||
//
|
||||
usingMutableMapBuilder = usingMutableMap.toBuilder();
|
||||
updateMapValuesUsingMutableMap(usingMutableMapBuilder);
|
||||
usingMutableMap = usingMutableMapBuilder.build();
|
||||
@ -335,7 +337,7 @@ public class MapForProto2Test extends TestCase {
|
||||
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
|
||||
builder.getMutableInt32ToInt32Field().put(2, 3);
|
||||
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
|
||||
|
||||
//
|
||||
Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField();
|
||||
enumMap.put(1, TestMap.EnumValue.BAR);
|
||||
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
|
||||
@ -350,7 +352,7 @@ public class MapForProto2Test extends TestCase {
|
||||
assertEquals(
|
||||
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
|
||||
builder.getInt32ToEnumField());
|
||||
|
||||
//
|
||||
Map<Integer, String> stringMap = builder.getMutableInt32ToStringField();
|
||||
stringMap.put(1, "1");
|
||||
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
|
||||
@ -365,7 +367,7 @@ public class MapForProto2Test extends TestCase {
|
||||
assertEquals(
|
||||
newMap(1, "1", 2, "2"),
|
||||
builder.getInt32ToStringField());
|
||||
|
||||
//
|
||||
Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField();
|
||||
messageMap.put(1, TestMap.MessageValue.getDefaultInstance());
|
||||
assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
|
||||
@ -384,7 +386,7 @@ public class MapForProto2Test extends TestCase {
|
||||
2, TestMap.MessageValue.getDefaultInstance()),
|
||||
builder.getInt32ToMessageField());
|
||||
}
|
||||
|
||||
//
|
||||
public void testMutableMapLifecycle_collections() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
|
||||
@ -431,18 +433,19 @@ public class MapForProto2Test extends TestCase {
|
||||
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
|
||||
}
|
||||
|
||||
|
||||
public void testGettersAndSetters() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
TestMap message = builder.build();
|
||||
assertMapValuesCleared(message);
|
||||
|
||||
builder = message.toBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
message = builder.build();
|
||||
assertMapValuesSet(message);
|
||||
|
||||
builder = message.toBuilder();
|
||||
updateMapValuesUsingMutableMap(builder);
|
||||
updateMapValuesUsingAccessors(builder);
|
||||
message = builder.build();
|
||||
assertMapValuesUpdated(message);
|
||||
|
||||
@ -455,7 +458,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testPutAll() throws Exception {
|
||||
TestMap.Builder sourceBuilder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(sourceBuilder);
|
||||
setMapValuesUsingAccessors(sourceBuilder);
|
||||
TestMap source = sourceBuilder.build();
|
||||
assertMapValuesSet(source);
|
||||
|
||||
@ -507,14 +510,14 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testSerializeAndParse() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
assertEquals(message.getSerializedSize(), message.toByteString().size());
|
||||
message = TestMap.parser().parseFrom(message.toByteString());
|
||||
assertMapValuesSet(message);
|
||||
|
||||
builder = message.toBuilder();
|
||||
updateMapValuesUsingMutableMap(builder);
|
||||
updateMapValuesUsingAccessors(builder);
|
||||
message = builder.build();
|
||||
assertEquals(message.getSerializedSize(), message.toByteString().size());
|
||||
message = TestMap.parser().parseFrom(message.toByteString());
|
||||
@ -579,7 +582,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testMergeFrom() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
TestMap.Builder other = TestMap.newBuilder();
|
||||
@ -594,22 +597,22 @@ public class MapForProto2Test extends TestCase {
|
||||
// We can't control the order of elements in a HashMap. The best we can do
|
||||
// here is to add elements in different order.
|
||||
TestMap.Builder b1 = TestMap.newBuilder();
|
||||
b1.getMutableInt32ToInt32Field().put(1, 2);
|
||||
b1.getMutableInt32ToInt32Field().put(3, 4);
|
||||
b1.getMutableInt32ToInt32Field().put(5, 6);
|
||||
b1.putInt32ToInt32Field(1, 2);
|
||||
b1.putInt32ToInt32Field(3, 4);
|
||||
b1.putInt32ToInt32Field(5, 6);
|
||||
TestMap m1 = b1.build();
|
||||
|
||||
TestMap.Builder b2 = TestMap.newBuilder();
|
||||
b2.getMutableInt32ToInt32Field().put(5, 6);
|
||||
b2.getMutableInt32ToInt32Field().put(1, 2);
|
||||
b2.getMutableInt32ToInt32Field().put(3, 4);
|
||||
b2.putInt32ToInt32Field(5, 6);
|
||||
b2.putInt32ToInt32Field(1, 2);
|
||||
b2.putInt32ToInt32Field(3, 4);
|
||||
TestMap m2 = b2.build();
|
||||
|
||||
assertEquals(m1, m2);
|
||||
assertEquals(m1.hashCode(), m2.hashCode());
|
||||
|
||||
// Make sure we did compare map fields.
|
||||
b2.getMutableInt32ToInt32Field().put(1, 0);
|
||||
b2.putInt32ToInt32Field(1, 0);
|
||||
m2 = b2.build();
|
||||
assertFalse(m1.equals(m2));
|
||||
// Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
|
||||
@ -684,13 +687,11 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testReflectionApi() throws Exception {
|
||||
// In reflection API, map fields are just repeated message fields.
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
builder.getMutableInt32ToInt32Field().put(1, 2);
|
||||
builder.getMutableInt32ToInt32Field().put(3, 4);
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
11, MessageValue.newBuilder().setValue(22).build());
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
33, MessageValue.newBuilder().setValue(44).build());
|
||||
TestMap.Builder builder = TestMap.newBuilder()
|
||||
.putInt32ToInt32Field(1, 2)
|
||||
.putInt32ToInt32Field(3, 4)
|
||||
.putInt32ToMessageField(11, MessageValue.newBuilder().setValue(22).build())
|
||||
.putInt32ToMessageField(33, MessageValue.newBuilder().setValue(44).build());
|
||||
TestMap message = builder.build();
|
||||
|
||||
// Test getField(), getRepeatedFieldCount(), getRepeatedField().
|
||||
@ -760,7 +761,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testTextFormat() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
String textData = TextFormat.printToString(message);
|
||||
@ -774,7 +775,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testDynamicMessage() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
Message dynamicDefaultInstance =
|
||||
@ -819,10 +820,9 @@ public class MapForProto2Test extends TestCase {
|
||||
}
|
||||
|
||||
public void testUnknownEnumValues() throws Exception {
|
||||
TestUnknownEnumValue.Builder builder =
|
||||
TestUnknownEnumValue.newBuilder();
|
||||
builder.getMutableInt32ToInt32Field().put(1, 1);
|
||||
builder.getMutableInt32ToInt32Field().put(2, 54321);
|
||||
TestUnknownEnumValue.Builder builder = TestUnknownEnumValue.newBuilder()
|
||||
.putInt32ToInt32Field(1, 1)
|
||||
.putInt32ToInt32Field(2, 54321);
|
||||
ByteString data = builder.build().toByteString();
|
||||
|
||||
TestMap message = TestMap.parseFrom(data);
|
||||
@ -841,26 +841,21 @@ public class MapForProto2Test extends TestCase {
|
||||
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
|
||||
}
|
||||
|
||||
|
||||
public void testRequiredMessage() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
builder.getMutableRequiredMessageMap().put(0,
|
||||
MessageWithRequiredFields.newBuilder().buildPartial());
|
||||
builder.putRequiredMessageMap(0, MessageWithRequiredFields.newBuilder().buildPartial());
|
||||
TestMap message = builder.buildPartial();
|
||||
assertFalse(message.isInitialized());
|
||||
|
||||
builder.getMutableRequiredMessageMap().put(0,
|
||||
MessageWithRequiredFields.newBuilder().setValue(1).build());
|
||||
builder.putRequiredMessageMap(0, MessageWithRequiredFields.newBuilder().setValue(1).build());
|
||||
message = builder.build();
|
||||
assertTrue(message.isInitialized());
|
||||
}
|
||||
|
||||
public void testRecursiveMap() throws Exception {
|
||||
TestRecursiveMap.Builder builder = TestRecursiveMap.newBuilder();
|
||||
builder.getMutableRecursiveMapField().put(
|
||||
1, TestRecursiveMap.newBuilder().setValue(2).build());
|
||||
builder.getMutableRecursiveMapField().put(
|
||||
3, TestRecursiveMap.newBuilder().setValue(4).build());
|
||||
builder.putRecursiveMapField(1, TestRecursiveMap.newBuilder().setValue(2).build());
|
||||
builder.putRecursiveMapField(3, TestRecursiveMap.newBuilder().setValue(4).build());
|
||||
ByteString data = builder.build().toByteString();
|
||||
|
||||
TestRecursiveMap message = TestRecursiveMap.parseFrom(data);
|
||||
@ -870,7 +865,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testIterationOrder() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
assertEquals(Arrays.asList("1", "2", "3"),
|
||||
@ -879,7 +874,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testContains() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
assertMapContainsSetValues(builder);
|
||||
assertMapContainsSetValues(builder.build());
|
||||
}
|
||||
@ -920,7 +915,7 @@ public class MapForProto2Test extends TestCase {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
assertMapCounts(0, builder);
|
||||
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
assertMapCounts(3, builder);
|
||||
|
||||
TestMap message = builder.build();
|
||||
@ -1091,7 +1086,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
public void testRemove() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
|
||||
for (int times = 0; times < 2; times++) {
|
||||
builder.removeInt32ToInt32Field(1);
|
||||
@ -1137,7 +1132,7 @@ public class MapForProto2Test extends TestCase {
|
||||
|
||||
map_test.Message1.Builder builder =
|
||||
map_test.Message1.newBuilder();
|
||||
builder.getMutableMapField().put("key", true);
|
||||
builder.putMapField("key", true);
|
||||
map_test.Message1 message = builder.build();
|
||||
Message mapEntry = (Message) message.getRepeatedField(
|
||||
message.getDescriptorForType().findFieldByName("map_field"), 0);
|
||||
|
@ -60,26 +60,26 @@ public class MapTest extends TestCase {
|
||||
builder.getMutableInt32ToInt32Field().put(1, 11);
|
||||
builder.getMutableInt32ToInt32Field().put(2, 22);
|
||||
builder.getMutableInt32ToInt32Field().put(3, 33);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToStringField().put(1, "11");
|
||||
builder.getMutableInt32ToStringField().put(2, "22");
|
||||
builder.getMutableInt32ToStringField().put(3, "33");
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("11"));
|
||||
builder.getMutableInt32ToBytesField().put(2, TestUtil.toBytes("22"));
|
||||
builder.getMutableInt32ToBytesField().put(3, TestUtil.toBytes("33"));
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.FOO);
|
||||
builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.BAR);
|
||||
builder.getMutableInt32ToEnumField().put(3, TestMap.EnumValue.BAZ);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
1, MessageValue.newBuilder().setValue(11).build());
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
2, MessageValue.newBuilder().setValue(22).build());
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
3, MessageValue.newBuilder().setValue(33).build());
|
||||
|
||||
//
|
||||
builder.getMutableStringToInt32Field().put("1", 11);
|
||||
builder.getMutableStringToInt32Field().put("2", 22);
|
||||
builder.getMutableStringToInt32Field().put("3", 33);
|
||||
@ -122,6 +122,7 @@ public class MapTest extends TestCase {
|
||||
setMapValuesUsingAccessors(usingAccessorsBuilder);
|
||||
TestMap usingAccessors = usingAccessorsBuilder.build();
|
||||
assertMapValuesSet(usingAccessors);
|
||||
|
||||
assertEquals(usingAccessors, usingMutableMap);
|
||||
}
|
||||
|
||||
@ -171,25 +172,25 @@ public class MapTest extends TestCase {
|
||||
builder.getMutableInt32ToInt32Field().put(1, 111);
|
||||
builder.getMutableInt32ToInt32Field().remove(2);
|
||||
builder.getMutableInt32ToInt32Field().put(4, 44);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToStringField().put(1, "111");
|
||||
builder.getMutableInt32ToStringField().remove(2);
|
||||
builder.getMutableInt32ToStringField().put(4, "44");
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("111"));
|
||||
builder.getMutableInt32ToBytesField().remove(2);
|
||||
builder.getMutableInt32ToBytesField().put(4, TestUtil.toBytes("44"));
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.BAR);
|
||||
builder.getMutableInt32ToEnumField().remove(2);
|
||||
builder.getMutableInt32ToEnumField().put(4, TestMap.EnumValue.QUX);
|
||||
|
||||
//
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
1, MessageValue.newBuilder().setValue(111).build());
|
||||
builder.getMutableInt32ToMessageField().remove(2);
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
4, MessageValue.newBuilder().setValue(44).build());
|
||||
|
||||
//
|
||||
builder.getMutableStringToInt32Field().put("1", 111);
|
||||
builder.getMutableStringToInt32Field().remove("2");
|
||||
builder.getMutableStringToInt32Field().put("4", 44);
|
||||
@ -232,8 +233,9 @@ public class MapTest extends TestCase {
|
||||
setMapValuesUsingAccessors(usingAccessorsBuilder);
|
||||
TestMap usingAccessors = usingAccessorsBuilder.build();
|
||||
assertMapValuesSet(usingAccessors);
|
||||
assertEquals(usingAccessors, usingMutableMap);
|
||||
|
||||
assertEquals(usingAccessors, usingMutableMap);
|
||||
//
|
||||
usingMutableMapBuilder = usingMutableMap.toBuilder();
|
||||
updateMapValuesUsingMutableMap(usingMutableMapBuilder);
|
||||
usingMutableMap = usingMutableMapBuilder.build();
|
||||
@ -337,7 +339,7 @@ public class MapTest extends TestCase {
|
||||
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
|
||||
builder.getMutableInt32ToInt32Field().put(2, 3);
|
||||
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
|
||||
|
||||
//
|
||||
Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField();
|
||||
enumMap.put(1, TestMap.EnumValue.BAR);
|
||||
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
|
||||
@ -352,7 +354,7 @@ public class MapTest extends TestCase {
|
||||
assertEquals(
|
||||
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
|
||||
builder.getInt32ToEnumField());
|
||||
|
||||
//
|
||||
Map<Integer, String> stringMap = builder.getMutableInt32ToStringField();
|
||||
stringMap.put(1, "1");
|
||||
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
|
||||
@ -363,11 +365,11 @@ public class MapTest extends TestCase {
|
||||
// expected
|
||||
}
|
||||
assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
|
||||
builder.getMutableInt32ToStringField().put(2, "2");
|
||||
builder.putInt32ToStringField(2, "2");
|
||||
assertEquals(
|
||||
newMap(1, "1", 2, "2"),
|
||||
builder.getInt32ToStringField());
|
||||
|
||||
//
|
||||
Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField();
|
||||
messageMap.put(1, TestMap.MessageValue.getDefaultInstance());
|
||||
assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
|
||||
@ -380,13 +382,13 @@ public class MapTest extends TestCase {
|
||||
}
|
||||
assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
|
||||
builder.getInt32ToMessageField());
|
||||
builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance());
|
||||
builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
|
||||
assertEquals(
|
||||
newMap(1, TestMap.MessageValue.getDefaultInstance(),
|
||||
2, TestMap.MessageValue.getDefaultInstance()),
|
||||
builder.getInt32ToMessageField());
|
||||
}
|
||||
|
||||
//
|
||||
public void testMutableMapLifecycle_collections() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
|
||||
@ -433,18 +435,19 @@ public class MapTest extends TestCase {
|
||||
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
|
||||
}
|
||||
|
||||
|
||||
public void testGettersAndSetters() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
TestMap message = builder.build();
|
||||
assertMapValuesCleared(message);
|
||||
|
||||
builder = message.toBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
message = builder.build();
|
||||
assertMapValuesSet(message);
|
||||
|
||||
builder = message.toBuilder();
|
||||
updateMapValuesUsingMutableMap(builder);
|
||||
updateMapValuesUsingAccessors(builder);
|
||||
message = builder.build();
|
||||
assertMapValuesUpdated(message);
|
||||
|
||||
@ -457,7 +460,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testPutAll() throws Exception {
|
||||
TestMap.Builder sourceBuilder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(sourceBuilder);
|
||||
setMapValuesUsingAccessors(sourceBuilder);
|
||||
TestMap source = sourceBuilder.build();
|
||||
assertMapValuesSet(source);
|
||||
|
||||
@ -467,15 +470,16 @@ public class MapTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testPutAllForUnknownEnumValues() throws Exception {
|
||||
TestMap.Builder sourceBuilder = TestMap.newBuilder();
|
||||
sourceBuilder.getMutableInt32ToEnumFieldValue().put(0, 0);
|
||||
sourceBuilder.getMutableInt32ToEnumFieldValue().put(1, 1);
|
||||
sourceBuilder.getMutableInt32ToEnumFieldValue().put(2, 1000); // unknown value.
|
||||
TestMap source = sourceBuilder.build();
|
||||
TestMap source = TestMap.newBuilder()
|
||||
.putAllInt32ToEnumFieldValue(newMap(
|
||||
0, 0,
|
||||
1, 1,
|
||||
2, 1000)) // unknown value.
|
||||
.build();
|
||||
|
||||
TestMap.Builder destinationBuilder = TestMap.newBuilder();
|
||||
destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue());
|
||||
TestMap destination = destinationBuilder.build();
|
||||
TestMap destination = TestMap.newBuilder()
|
||||
.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue())
|
||||
.build();
|
||||
|
||||
assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
|
||||
assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
|
||||
@ -542,14 +546,14 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testSerializeAndParse() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
assertEquals(message.getSerializedSize(), message.toByteString().size());
|
||||
message = TestMap.parser().parseFrom(message.toByteString());
|
||||
assertMapValuesSet(message);
|
||||
|
||||
builder = message.toBuilder();
|
||||
updateMapValuesUsingMutableMap(builder);
|
||||
updateMapValuesUsingAccessors(builder);
|
||||
message = builder.build();
|
||||
assertEquals(message.getSerializedSize(), message.toByteString().size());
|
||||
message = TestMap.parser().parseFrom(message.toByteString());
|
||||
@ -614,7 +618,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testMergeFrom() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
TestMap.Builder other = TestMap.newBuilder();
|
||||
@ -628,23 +632,23 @@ public class MapTest extends TestCase {
|
||||
|
||||
// We can't control the order of elements in a HashMap. The best we can do
|
||||
// here is to add elements in different order.
|
||||
TestMap.Builder b1 = TestMap.newBuilder();
|
||||
b1.getMutableInt32ToInt32Field().put(1, 2);
|
||||
b1.getMutableInt32ToInt32Field().put(3, 4);
|
||||
b1.getMutableInt32ToInt32Field().put(5, 6);
|
||||
TestMap.Builder b1 = TestMap.newBuilder()
|
||||
.putInt32ToInt32Field(1, 2)
|
||||
.putInt32ToInt32Field(3, 4)
|
||||
.putInt32ToInt32Field(5, 6);
|
||||
TestMap m1 = b1.build();
|
||||
|
||||
TestMap.Builder b2 = TestMap.newBuilder();
|
||||
b2.getMutableInt32ToInt32Field().put(5, 6);
|
||||
b2.getMutableInt32ToInt32Field().put(1, 2);
|
||||
b2.getMutableInt32ToInt32Field().put(3, 4);
|
||||
TestMap.Builder b2 = TestMap.newBuilder()
|
||||
.putInt32ToInt32Field(5, 6)
|
||||
.putInt32ToInt32Field(1, 2)
|
||||
.putInt32ToInt32Field(3, 4);
|
||||
TestMap m2 = b2.build();
|
||||
|
||||
assertEquals(m1, m2);
|
||||
assertEquals(m1.hashCode(), m2.hashCode());
|
||||
|
||||
// Make sure we did compare map fields.
|
||||
b2.getMutableInt32ToInt32Field().put(1, 0);
|
||||
b2.putInt32ToInt32Field(1, 0);
|
||||
m2 = b2.build();
|
||||
assertFalse(m1.equals(m2));
|
||||
// Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
|
||||
@ -652,7 +656,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
// Regression test for b/18549190: if a map is a subset of the other map,
|
||||
// equals() should return false.
|
||||
b2.getMutableInt32ToInt32Field().remove(1);
|
||||
b2.removeInt32ToInt32Field(1);
|
||||
m2 = b2.build();
|
||||
assertFalse(m1.equals(m2));
|
||||
assertFalse(m2.equals(m1));
|
||||
@ -661,20 +665,19 @@ public class MapTest extends TestCase {
|
||||
public void testNestedBuilderOnChangeEventPropagation() {
|
||||
TestOnChangeEventPropagation.Builder parent =
|
||||
TestOnChangeEventPropagation.newBuilder();
|
||||
parent.getOptionalMessageBuilder().getMutableInt32ToInt32Field().put(1, 2);
|
||||
parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2);
|
||||
TestOnChangeEventPropagation message = parent.build();
|
||||
assertEquals(2, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
|
||||
|
||||
// Make a change using nested builder.
|
||||
parent.getOptionalMessageBuilder().getMutableInt32ToInt32Field().put(1, 3);
|
||||
parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3);
|
||||
|
||||
// Should be able to observe the change.
|
||||
message = parent.build();
|
||||
assertEquals(3, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
|
||||
|
||||
// Make another change using mergeFrom()
|
||||
TestMap.Builder other = TestMap.newBuilder();
|
||||
other.getMutableInt32ToInt32Field().put(1, 4);
|
||||
TestMap.Builder other = TestMap.newBuilder().putInt32ToInt32Field(1, 4);
|
||||
parent.getOptionalMessageBuilder().mergeFrom(other.build());
|
||||
|
||||
// Should be able to observe the change.
|
||||
@ -697,8 +700,7 @@ public class MapTest extends TestCase {
|
||||
TestMap.Builder testMapBuilder = parentBuilder.getOptionalMessageBuilder();
|
||||
|
||||
// Create a map entry message.
|
||||
TestMap.Builder entryBuilder = TestMap.newBuilder();
|
||||
entryBuilder.getMutableInt32ToInt32Field().put(1, 1);
|
||||
TestMap.Builder entryBuilder = TestMap.newBuilder().putInt32ToInt32Field(1, 1);
|
||||
|
||||
// Put the entry into the nested builder.
|
||||
testMapBuilder.addRepeatedField(
|
||||
@ -709,7 +711,7 @@ public class MapTest extends TestCase {
|
||||
assertEquals(1, message.getOptionalMessage().getInt32ToInt32Field().size());
|
||||
|
||||
// Change the entry value.
|
||||
entryBuilder.getMutableInt32ToInt32Field().put(1, 4);
|
||||
entryBuilder.putInt32ToInt32Field(1, 4);
|
||||
testMapBuilder = parentBuilder.getOptionalMessageBuilder();
|
||||
testMapBuilder.setRepeatedField(
|
||||
intMapField, 0, entryBuilder.getRepeatedField(intMapField, 0));
|
||||
@ -796,13 +798,11 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testReflectionApi() throws Exception {
|
||||
// In reflection API, map fields are just repeated message fields.
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
builder.getMutableInt32ToInt32Field().put(1, 2);
|
||||
builder.getMutableInt32ToInt32Field().put(3, 4);
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
11, MessageValue.newBuilder().setValue(22).build());
|
||||
builder.getMutableInt32ToMessageField().put(
|
||||
33, MessageValue.newBuilder().setValue(44).build());
|
||||
TestMap.Builder builder = TestMap.newBuilder()
|
||||
.putInt32ToInt32Field(1, 2)
|
||||
.putInt32ToInt32Field(3, 4)
|
||||
.putInt32ToMessageField(11, MessageValue.newBuilder().setValue(22).build())
|
||||
.putInt32ToMessageField(33, MessageValue.newBuilder().setValue(44).build());
|
||||
TestMap message = builder.build();
|
||||
|
||||
// Test getField(), getRepeatedFieldCount(), getRepeatedField().
|
||||
@ -872,7 +872,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testTextFormat() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
String textData = TextFormat.printToString(message);
|
||||
@ -886,7 +886,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testDynamicMessage() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
Message dynamicDefaultInstance =
|
||||
@ -931,10 +931,11 @@ public class MapTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testUnknownEnumValues() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
builder.getMutableInt32ToEnumFieldValue().put(0, 0);
|
||||
builder.getMutableInt32ToEnumFieldValue().put(1, 1);
|
||||
builder.getMutableInt32ToEnumFieldValue().put(2, 1000); // unknown value.
|
||||
TestMap.Builder builder = TestMap.newBuilder()
|
||||
.putAllInt32ToEnumFieldValue(newMap(
|
||||
0, 0,
|
||||
1, 1,
|
||||
2, 1000)); // unknown value.
|
||||
TestMap message = builder.build();
|
||||
|
||||
assertEquals(TestMap.EnumValue.FOO,
|
||||
@ -957,7 +958,7 @@ public class MapTest extends TestCase {
|
||||
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
|
||||
|
||||
// hashCode()/equals() should take unknown enum values into account.
|
||||
builder.getMutableInt32ToEnumFieldValue().put(2, 1001);
|
||||
builder.putAllInt32ToEnumFieldValue(newMap(2, 1001));
|
||||
TestMap message2 = builder.build();
|
||||
assertFalse(message.hashCode() == message2.hashCode());
|
||||
assertFalse(message.equals(message2));
|
||||
@ -971,15 +972,13 @@ public class MapTest extends TestCase {
|
||||
EnumDescriptor enumDescriptor = TestMap.EnumValue.getDescriptor();
|
||||
FieldDescriptor field = descriptor.findFieldByName("int32_to_enum_field");
|
||||
|
||||
Map<Integer, Integer> data = new HashMap<Integer, Integer>();
|
||||
data.put(0, 0);
|
||||
data.put(1, 1);
|
||||
data.put(2, 1000); // unknown value.
|
||||
Map<Integer, Integer> data = newMap(
|
||||
0, 0,
|
||||
1, 1,
|
||||
2, 1000); // unknown value
|
||||
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
for (Map.Entry<Integer, Integer> entry : data.entrySet()) {
|
||||
builder.getMutableInt32ToEnumFieldValue().put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
TestMap.Builder builder = TestMap.newBuilder()
|
||||
.putAllInt32ToEnumFieldValue(data);
|
||||
|
||||
// Try to read unknown enum values using reflection API.
|
||||
for (int i = 0; i < builder.getRepeatedFieldCount(field); i++) {
|
||||
@ -1003,7 +1002,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testIterationOrder() throws Exception {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
assertEquals(Arrays.asList("1", "2", "3"),
|
||||
@ -1012,7 +1011,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testGetMap() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
assertEquals(
|
||||
message.getStringToInt32Field(),
|
||||
@ -1033,7 +1032,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testContains() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
assertMapContainsSetValues(builder);
|
||||
assertMapContainsSetValues(builder.build());
|
||||
}
|
||||
@ -1074,7 +1073,7 @@ public class MapTest extends TestCase {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
assertMapCounts(0, builder);
|
||||
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
assertMapCounts(3, builder);
|
||||
|
||||
TestMap message = builder.build();
|
||||
@ -1269,7 +1268,7 @@ public class MapTest extends TestCase {
|
||||
|
||||
public void testRemove() {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
setMapValuesUsingMutableMap(builder);
|
||||
setMapValuesUsingAccessors(builder);
|
||||
assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
|
||||
for (int times = 0; times < 2; times++) {
|
||||
builder.removeInt32ToInt32Field(1);
|
||||
@ -1485,4 +1484,12 @@ public class MapTest extends TestCase {
|
||||
map.put(key2, value2);
|
||||
return map;
|
||||
}
|
||||
|
||||
private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2, K key3, V value3) {
|
||||
Map<K, V> map = new HashMap<K, V>();
|
||||
map.put(key1, value1);
|
||||
map.put(key2, value2);
|
||||
map.put(key3, value3);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -372,4 +373,43 @@ public class ParserTest extends TestCase {
|
||||
assertEquals(3, parsingMerge.getExtensionCount(
|
||||
TestParsingMergeLite.repeatedExt));
|
||||
}
|
||||
|
||||
public void testParseDelimitedFrom_firstByteInterrupted_preservesCause() {
|
||||
try {
|
||||
TestUtil.getAllSet().parseDelimitedFrom(
|
||||
new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
});
|
||||
fail("Expected InterruptedIOException");
|
||||
} catch (Exception e) {
|
||||
assertEquals(InterruptedIOException.class, e.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseDelimitedFrom_secondByteInterrupted_preservesCause() {
|
||||
try {
|
||||
TestUtil.getAllSet().parseDelimitedFrom(
|
||||
new InputStream() {
|
||||
private int i;
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
switch (i++) {
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
throw new InterruptedIOException();
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
});
|
||||
fail("Expected InterruptedIOException");
|
||||
} catch (Exception e) {
|
||||
assertEquals(InterruptedIOException.class, e.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ import static com.google.protobuf.util.Timestamps.NANOS_PER_MICROSECOND;
|
||||
import static com.google.protobuf.util.Timestamps.NANOS_PER_MILLISECOND;
|
||||
import static com.google.protobuf.util.Timestamps.NANOS_PER_SECOND;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.protobuf.Duration;
|
||||
import java.text.ParseException;
|
||||
import java.util.Comparator;
|
||||
@ -71,11 +70,8 @@ public final class Durations {
|
||||
public int compare(Duration d1, Duration d2) {
|
||||
checkValid(d1);
|
||||
checkValid(d2);
|
||||
|
||||
return ComparisonChain.start()
|
||||
.compare(d1.getSeconds(), d2.getSeconds())
|
||||
.compare(d1.getNanos(), d2.getNanos())
|
||||
.result();
|
||||
int secDiff = Long.compare(d1.getSeconds(), d2.getSeconds());
|
||||
return (secDiff != 0) ? secDiff : Integer.compare(d1.getNanos(), d2.getNanos());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -217,7 +217,12 @@ final class FieldMaskTree {
|
||||
Message source,
|
||||
Message.Builder destination,
|
||||
FieldMaskUtil.MergeOptions options) {
|
||||
assert source.getDescriptorForType() == destination.getDescriptorForType();
|
||||
if (source.getDescriptorForType() != destination.getDescriptorForType()) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"source (%s) and destination (%s) descriptor must be equal",
|
||||
source.getDescriptorForType(), destination.getDescriptorForType()));
|
||||
}
|
||||
|
||||
Descriptor descriptor = source.getDescriptorForType();
|
||||
for (Entry<String, Node> entry : node.children.entrySet()) {
|
||||
|
@ -67,7 +67,6 @@ import com.google.protobuf.Timestamp;
|
||||
import com.google.protobuf.UInt32Value;
|
||||
import com.google.protobuf.UInt64Value;
|
||||
import com.google.protobuf.Value;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
@ -224,7 +223,7 @@ public class JsonFormat {
|
||||
* Creates a {@link Parser} with default configuration.
|
||||
*/
|
||||
public static Parser parser() {
|
||||
return new Parser(TypeRegistry.getEmptyTypeRegistry(), false);
|
||||
return new Parser(TypeRegistry.getEmptyTypeRegistry(), false, Parser.DEFAULT_RECURSION_LIMIT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,10 +232,15 @@ public class JsonFormat {
|
||||
public static class Parser {
|
||||
private final TypeRegistry registry;
|
||||
private final boolean ignoringUnknownFields;
|
||||
private final int recursionLimit;
|
||||
|
||||
private Parser(TypeRegistry registry, boolean ignoreUnknownFields) {
|
||||
// The default parsing recursion limit is aligned with the proto binary parser.
|
||||
private static final int DEFAULT_RECURSION_LIMIT = 100;
|
||||
|
||||
private Parser(TypeRegistry registry, boolean ignoreUnknownFields, int recursionLimit) {
|
||||
this.registry = registry;
|
||||
this.ignoringUnknownFields = ignoreUnknownFields;
|
||||
this.recursionLimit = recursionLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,16 +253,15 @@ public class JsonFormat {
|
||||
if (this.registry != TypeRegistry.getEmptyTypeRegistry()) {
|
||||
throw new IllegalArgumentException("Only one registry is allowed.");
|
||||
}
|
||||
return new Parser(registry, this.ignoringUnknownFields);
|
||||
return new Parser(registry, ignoringUnknownFields, recursionLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Parser} configured to not throw an exception
|
||||
* when an unknown field is encountered. The new Parser clones all other
|
||||
* configurations from this Parser.
|
||||
* Creates a new {@link Parser} configured to not throw an exception when an unknown field is
|
||||
* encountered. The new Parser clones all other configurations from this Parser.
|
||||
*/
|
||||
public Parser ignoringUnknownFields() {
|
||||
return new Parser(this.registry, true);
|
||||
return new Parser(this.registry, true, recursionLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,7 +273,7 @@ public class JsonFormat {
|
||||
public void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException {
|
||||
// TODO(xiaofeng): Investigate the allocation overhead and optimize for
|
||||
// mobile.
|
||||
new ParserImpl(registry, ignoringUnknownFields).merge(json, builder);
|
||||
new ParserImpl(registry, ignoringUnknownFields, recursionLimit).merge(json, builder);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,7 +286,12 @@ public class JsonFormat {
|
||||
public void merge(Reader json, Message.Builder builder) throws IOException {
|
||||
// TODO(xiaofeng): Investigate the allocation overhead and optimize for
|
||||
// mobile.
|
||||
new ParserImpl(registry, ignoringUnknownFields).merge(json, builder);
|
||||
new ParserImpl(registry, ignoringUnknownFields, recursionLimit).merge(json, builder);
|
||||
}
|
||||
|
||||
// For testing only.
|
||||
Parser usingRecursionLimit(int recursionLimit) {
|
||||
return new Parser(registry, ignoringUnknownFields, recursionLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1040,11 +1048,15 @@ public class JsonFormat {
|
||||
private final TypeRegistry registry;
|
||||
private final JsonParser jsonParser;
|
||||
private final boolean ignoringUnknownFields;
|
||||
private final int recursionLimit;
|
||||
private int currentDepth;
|
||||
|
||||
ParserImpl(TypeRegistry registry, boolean ignoreUnknownFields) {
|
||||
ParserImpl(TypeRegistry registry, boolean ignoreUnknownFields, int recursionLimit) {
|
||||
this.registry = registry;
|
||||
this.ignoringUnknownFields = ignoreUnknownFields;
|
||||
this.jsonParser = new JsonParser();
|
||||
this.recursionLimit = recursionLimit;
|
||||
this.currentDepth = 0;
|
||||
}
|
||||
|
||||
void merge(Reader json, Message.Builder builder) throws IOException {
|
||||
@ -1715,8 +1727,13 @@ public class JsonFormat {
|
||||
|
||||
case MESSAGE:
|
||||
case GROUP:
|
||||
if (currentDepth >= recursionLimit) {
|
||||
throw new InvalidProtocolBufferException("Hit recursion limit.");
|
||||
}
|
||||
++currentDepth;
|
||||
Message.Builder subBuilder = builder.newBuilderForField(field);
|
||||
merge(json, subBuilder);
|
||||
--currentDepth;
|
||||
return subBuilder.build();
|
||||
|
||||
default:
|
||||
|
@ -37,7 +37,6 @@ import static com.google.common.math.LongMath.checkedAdd;
|
||||
import static com.google.common.math.LongMath.checkedMultiply;
|
||||
import static com.google.common.math.LongMath.checkedSubtract;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.protobuf.Duration;
|
||||
import com.google.protobuf.Timestamp;
|
||||
import java.text.ParseException;
|
||||
@ -101,11 +100,8 @@ public final class Timestamps {
|
||||
public int compare(Timestamp t1, Timestamp t2) {
|
||||
checkValid(t1);
|
||||
checkValid(t2);
|
||||
|
||||
return ComparisonChain.start()
|
||||
.compare(t1.getSeconds(), t2.getSeconds())
|
||||
.compare(t1.getNanos(), t2.getNanos())
|
||||
.result();
|
||||
int secDiff = Long.compare(t1.getSeconds(), t2.getSeconds());
|
||||
return (secDiff != 0) ? secDiff : Integer.compare(t1.getNanos(), t2.getNanos());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -57,12 +57,15 @@ import com.google.protobuf.util.JsonTestProto.TestDuration;
|
||||
import com.google.protobuf.util.JsonTestProto.TestFieldMask;
|
||||
import com.google.protobuf.util.JsonTestProto.TestMap;
|
||||
import com.google.protobuf.util.JsonTestProto.TestOneof;
|
||||
import com.google.protobuf.util.JsonTestProto.TestRecursive;
|
||||
import com.google.protobuf.util.JsonTestProto.TestStruct;
|
||||
import com.google.protobuf.util.JsonTestProto.TestTimestamp;
|
||||
import com.google.protobuf.util.JsonTestProto.TestWrappers;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class JsonFormatTest extends TestCase {
|
||||
@ -216,7 +219,9 @@ public class JsonFormatTest extends TestCase {
|
||||
|
||||
TestMap.Builder mapBuilder = TestMap.newBuilder();
|
||||
mapBuilder.putInt32ToEnumMapValue(1, 0);
|
||||
mapBuilder.getMutableInt32ToEnumMapValue().put(2, 12345);
|
||||
Map<Integer, Integer> mapWithInvalidValues = new HashMap<Integer, Integer>();
|
||||
mapWithInvalidValues.put(2, 12345);
|
||||
mapBuilder.putAllInt32ToEnumMapValue(mapWithInvalidValues);
|
||||
TestMap mapMessage = mapBuilder.build();
|
||||
assertEquals(
|
||||
"{\n"
|
||||
@ -1140,6 +1145,7 @@ public class JsonFormatTest extends TestCase {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
public void testParserIgnoringUnknownFields() throws Exception {
|
||||
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
|
||||
String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}";
|
||||
@ -1358,4 +1364,34 @@ public class JsonFormatTest extends TestCase {
|
||||
Any any = builder.build();
|
||||
assertEquals(0, any.getValue().size());
|
||||
}
|
||||
|
||||
public void testRecursionLimit() throws Exception {
|
||||
String input =
|
||||
"{\n"
|
||||
+ " \"nested\": {\n"
|
||||
+ " \"nested\": {\n"
|
||||
+ " \"nested\": {\n"
|
||||
+ " \"nested\": {\n"
|
||||
+ " \"value\": 1234\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ "}\n";
|
||||
|
||||
JsonFormat.Parser parser = JsonFormat.parser();
|
||||
TestRecursive.Builder builder = TestRecursive.newBuilder();
|
||||
parser.merge(input, builder);
|
||||
TestRecursive message = builder.build();
|
||||
assertEquals(1234, message.getNested().getNested().getNested().getNested().getValue());
|
||||
|
||||
parser = JsonFormat.parser().usingRecursionLimit(3);
|
||||
builder = TestRecursive.newBuilder();
|
||||
try {
|
||||
parser.merge(input, builder);
|
||||
fail("Exception is expected.");
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,3 +201,8 @@ message TestAny {
|
||||
message TestCustomJsonName {
|
||||
int32 value = 1 [json_name = "@value"];
|
||||
}
|
||||
|
||||
message TestRecursive {
|
||||
int32 value = 1;
|
||||
TestRecursive nested = 2;
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ docker run \
|
||||
"$@" \
|
||||
-e CCACHE_DIR=$CCACHE_DIR \
|
||||
-e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \
|
||||
-e TEST_SET="$TEST_SET" \
|
||||
-e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
|
||||
-v "$git_root:/var/local/jenkins/protobuf:ro" \
|
||||
-v $CCACHE_DIR:$CCACHE_DIR \
|
||||
|
@ -12,5 +12,4 @@
|
||||
export DOCKERFILE_DIR=jenkins/docker
|
||||
export DOCKER_RUN_SCRIPT=jenkins/pull_request_in_docker.sh
|
||||
export OUTPUT_DIR=testoutput
|
||||
export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
|
||||
./jenkins/build_and_run_docker.sh
|
||||
|
@ -14,29 +14,25 @@ RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > /
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB82666C
|
||||
|
||||
# Apt source for Oracle Java.
|
||||
RUN echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \
|
||||
run echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && \
|
||||
echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections
|
||||
|
||||
# Apt source for Mono
|
||||
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \
|
||||
run echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \
|
||||
echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list && \
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
||||
|
||||
# Apt source for php
|
||||
RUN echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu trusty main" | tee /etc/apt/sources.list.d/various-php.list && \
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F4FCBB07
|
||||
|
||||
# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
|
||||
# (Ubuntu instructions need apt to support https)
|
||||
RUN apt-get update && apt-get install -y --force-yes curl libunwind8 gettext && \
|
||||
curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 && \
|
||||
RUN apt-get update && apt-get install -y curl libunwind8 gettext && \
|
||||
curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 && \
|
||||
mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet && \
|
||||
ln -s /opt/dotnet/dotnet /usr/local/bin
|
||||
|
||||
# Install dependencies. We start with the basic ones require to build protoc
|
||||
# and the C++ build
|
||||
RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
|
||||
RUN apt-get update && apt-get install -y \
|
||||
autoconf \
|
||||
autotools-dev \
|
||||
build-essential \
|
||||
@ -75,21 +71,6 @@ RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
|
||||
python3.4-dev \
|
||||
# -- For Ruby --
|
||||
ruby \
|
||||
# -- For C++ benchmarks --
|
||||
cmake \
|
||||
# -- For PHP --
|
||||
php5.5 \
|
||||
php5.5-dev \
|
||||
php5.5-xml \
|
||||
php5.6 \
|
||||
php5.6-dev \
|
||||
php5.6-xml \
|
||||
php7.0 \
|
||||
php7.0-dev \
|
||||
php7.0-xml \
|
||||
phpunit \
|
||||
valgrind \
|
||||
libxml2-dev \
|
||||
&& apt-get clean
|
||||
|
||||
##################
|
||||
@ -134,41 +115,12 @@ RUN cd /tmp && \
|
||||
cd protobuf && \
|
||||
./autogen.sh && \
|
||||
./configure && \
|
||||
make -j4 && \
|
||||
make -j6 && \
|
||||
cd java && \
|
||||
$MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO && \
|
||||
cd ../javanano && \
|
||||
$MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO
|
||||
|
||||
##################
|
||||
# PHP dependencies.
|
||||
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
RUN php composer-setup.php
|
||||
RUN mv composer.phar /usr/bin/composer
|
||||
RUN php -r "unlink('composer-setup.php');"
|
||||
RUN cd /tmp && \
|
||||
cd protobuf && \
|
||||
ln -sfn /usr/bin/php5.5 /usr/bin/php && \
|
||||
ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config && \
|
||||
ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize && \
|
||||
composer install && \
|
||||
mv vendor /usr/local/vendor-5.5 && \
|
||||
ln -sfn /usr/bin/php5.6 /usr/bin/php && \
|
||||
ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config && \
|
||||
ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize && \
|
||||
composer install && \
|
||||
mv vendor /usr/local/vendor-5.6 && \
|
||||
ln -sfn /usr/bin/php7.0 /usr/bin/php && \
|
||||
ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config && \
|
||||
ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize && \
|
||||
composer install && \
|
||||
mv vendor /usr/local/vendor-7.0
|
||||
RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror
|
||||
RUN mv mirror php-5.5.38.tar.bz2
|
||||
RUN tar -xvf php-5.5.38.tar.bz2
|
||||
RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \
|
||||
make && make install
|
||||
|
||||
##################
|
||||
# Go dependencies.
|
||||
RUN apt-get install -y \
|
||||
@ -177,7 +129,7 @@ RUN apt-get install -y \
|
||||
|
||||
##################
|
||||
# Javascript dependencies.
|
||||
RUN apt-get install -y \
|
||||
Run apt-get install -y \
|
||||
# -- For javascript -- \
|
||||
npm
|
||||
|
||||
|
@ -45,11 +45,19 @@ TIME_CMD="/usr/bin/time -f %e -o $LOG_OUTPUT_DIR/1/cpp/build_time"
|
||||
|
||||
$TIME_CMD $TEST_SCRIPT cpp > >(tee $CPP_STDOUT) 2> >(tee $CPP_STDERR >&2)
|
||||
|
||||
# Other tests are run in parallel. TEST_SET is defined in
|
||||
# buildcmds/pull_request{_32}.sh
|
||||
# Other tests are run in parallel.
|
||||
|
||||
parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: \
|
||||
$TEST_SET \
|
||||
csharp \
|
||||
java_jdk7 \
|
||||
javanano_jdk7 \
|
||||
java_oracle7 \
|
||||
javanano_oracle7 \
|
||||
python \
|
||||
python_cpp \
|
||||
ruby_all \
|
||||
javascript \
|
||||
golang \
|
||||
|| true # Process test results even if tests fail.
|
||||
|
||||
cat $OUTPUT_DIR/joblog
|
||||
|
@ -732,6 +732,24 @@ jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed, zigzag-encoded 64-bit varint from the binary stream and
|
||||
* returns its valud as a string.
|
||||
*
|
||||
* Zigzag encoding is a modification of varint encoding that reduces the
|
||||
* storage overhead for small negative integers - for more details on the
|
||||
* format, see https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @return {string} The decoded signed, zigzag-encoded 64-bit varint as a
|
||||
* string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readZigzagVarint64String = function() {
|
||||
// TODO(haberman): write lossless 64-bit zig-zag math.
|
||||
var value = this.readZigzagVarint64();
|
||||
return value.toString();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 8-bit integer from the binary stream.
|
||||
*
|
||||
@ -790,6 +808,20 @@ jspb.BinaryDecoder.prototype.readUint64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 64-bit integer from the binary stream. Note that since
|
||||
* Javascript represents all numbers as double-precision floats, there will be
|
||||
* precision lost if the absolute value of the integer is larger than 2^53.
|
||||
*
|
||||
* @return {string} The unsigned 64-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUint64String = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 8-bit integer from the binary stream.
|
||||
*
|
||||
@ -848,6 +880,20 @@ jspb.BinaryDecoder.prototype.readInt64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 64-bit integer from the binary stream and returns it as a
|
||||
* string.
|
||||
*
|
||||
* @return {string} The signed 64-bit integer read from the binary stream.
|
||||
* Precision will be lost if the integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readInt64String = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32-bit floating-point number from the binary stream, using the
|
||||
* temporary buffer to realign the data.
|
||||
|
@ -99,6 +99,24 @@ jspb.BinaryEncoder.prototype.writeSplitVarint64 = function(lowBits, highBits) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a 64-bit integer in 32:32 split representation into its wire-format
|
||||
* fixed representation and stores it in the buffer.
|
||||
* @param {number} lowBits The low 32 bits of the int.
|
||||
* @param {number} highBits The high 32 bits of the int.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeSplitFixed64 = function(lowBits, highBits) {
|
||||
goog.asserts.assert(lowBits == Math.floor(lowBits));
|
||||
goog.asserts.assert(highBits == Math.floor(highBits));
|
||||
goog.asserts.assert((lowBits >= 0) &&
|
||||
(lowBits < jspb.BinaryConstants.TWO_TO_32));
|
||||
goog.asserts.assert((highBits >= 0) &&
|
||||
(highBits < jspb.BinaryConstants.TWO_TO_32));
|
||||
this.writeUint32(lowBits);
|
||||
this.writeUint32(highBits);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a 32-bit unsigned integer into its wire-format varint representation
|
||||
* and stores it in the buffer.
|
||||
@ -207,6 +225,18 @@ jspb.BinaryEncoder.prototype.writeZigzagVarint64 = function(value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a JavaScript decimal string into its wire-format, zigzag-encoded
|
||||
* varint representation and stores it in the buffer. Integers not representable
|
||||
* in 64 bits will be truncated.
|
||||
* @param {string} value The integer to convert.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeZigzagVarint64String = function(value) {
|
||||
// TODO(haberman): write lossless 64-bit zig-zag math.
|
||||
this.writeZigzagVarint64(parseInt(value, 10));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a 8-bit unsigned integer to the buffer. Numbers outside the range
|
||||
* [0,2^8) will be truncated.
|
||||
@ -314,8 +344,21 @@ jspb.BinaryEncoder.prototype.writeInt64 = function(value) {
|
||||
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
|
||||
(value < jspb.BinaryConstants.TWO_TO_63));
|
||||
jspb.utils.splitInt64(value);
|
||||
this.writeUint32(jspb.utils.split64Low);
|
||||
this.writeUint32(jspb.utils.split64High);
|
||||
this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a 64-bit integer decimal strings to the buffer. Numbers outside the
|
||||
* range [-2^63,2^63) will be truncated.
|
||||
* @param {string} value The value to write.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeInt64String = function(value) {
|
||||
goog.asserts.assert(value == Math.floor(value));
|
||||
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
|
||||
(value < jspb.BinaryConstants.TWO_TO_63));
|
||||
jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value));
|
||||
this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High);
|
||||
};
|
||||
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.Message');
|
||||
|
||||
// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test
|
||||
@ -87,6 +88,9 @@ goog.require('proto.jspb.test.extendRepeatedStringList');
|
||||
goog.require('proto.jspb.test.extendRepeatedUint32List');
|
||||
goog.require('proto.jspb.test.extendRepeatedUint64List');
|
||||
|
||||
// CommonJS-LoadFromFile: google/protobuf/any_pb proto.google.protobuf
|
||||
goog.require('proto.google.protobuf.Any');
|
||||
|
||||
|
||||
var suite = {};
|
||||
|
||||
@ -194,8 +198,6 @@ function bytesCompare(arr, expected) {
|
||||
* @param {proto.jspb.test.TestAllTypes} copy
|
||||
*/
|
||||
function checkAllFields(original, copy) {
|
||||
assertTrue(jspb.Message.equals(original, copy));
|
||||
|
||||
assertEquals(copy.getOptionalInt32(), -42);
|
||||
assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000);
|
||||
assertEquals(copy.getOptionalUint32(), 0x80000000);
|
||||
@ -270,6 +272,9 @@ function checkAllFields(original, copy) {
|
||||
assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]);
|
||||
assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]);
|
||||
|
||||
|
||||
// Check last so we get more granular errors first.
|
||||
assertTrue(jspb.Message.equals(original, copy));
|
||||
}
|
||||
|
||||
|
||||
@ -625,4 +630,36 @@ describe('protoBinaryTest', function() {
|
||||
var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
|
||||
checkExtensions(decoded);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that unknown extensions don't cause deserialization failure.
|
||||
*/
|
||||
it('testUnknownExtension', function() {
|
||||
var msg = new proto.jspb.test.TestExtendable();
|
||||
fillExtensions(msg);
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeBool((1 << 29) - 1, true);
|
||||
proto.jspb.test.TestExtendable.serializeBinaryToWriter(msg, writer);
|
||||
var encoded = writer.getResultBuffer();
|
||||
var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
|
||||
checkExtensions(decoded);
|
||||
});
|
||||
|
||||
it('testAnyWellKnownType', function() {
|
||||
var any = new proto.google.protobuf.Any();
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
|
||||
fillAllFields(msg);
|
||||
|
||||
any.pack(msg.serializeBinary(), 'jspb.test.TestAllTypes');
|
||||
|
||||
assertEquals('type.googleapis.com/jspb.test.TestAllTypes',
|
||||
any.getTypeUrl());
|
||||
|
||||
var msg2 = any.unpack(
|
||||
proto.jspb.test.TestAllTypes.deserializeBinary,
|
||||
'jspb.test.TestAllTypes');
|
||||
|
||||
checkAllFields(msg, msg2);
|
||||
});
|
||||
});
|
||||
|
@ -743,6 +743,20 @@ jspb.BinaryReader.prototype.readSint64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed zigzag-encoded 64-bit integer field from the binary stream,
|
||||
* or throws an error if the next field in the stream is not of the correct
|
||||
* wire type.
|
||||
*
|
||||
* @return {string} The value of the signed 64-bit integer field as a decimal string.
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readSint64String = function() {
|
||||
goog.asserts.assert(
|
||||
this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
|
||||
return this.decoder_.readZigzagVarint64String();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads an unsigned 32-bit fixed-length integer fiield from the binary stream,
|
||||
* or throws an error if the next field in the stream is not of the correct
|
||||
@ -771,12 +785,29 @@ jspb.BinaryReader.prototype.readFixed64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed 64-bit integer field from the binary stream as a string, or
|
||||
* throws an error if the next field in the stream is not of the correct wire
|
||||
* type.
|
||||
*
|
||||
* Returns the value as a string.
|
||||
*
|
||||
* @return {string} The value of the unsigned 64-bit integer field as a decimal
|
||||
* string.
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readFixed64String = function() {
|
||||
goog.asserts.assert(
|
||||
this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
|
||||
return this.decoder_.readUint64String();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed 32-bit fixed-length integer fiield from the binary stream, or
|
||||
* throws an error if the next field in the stream is not of the correct wire
|
||||
* type.
|
||||
*
|
||||
* @return {number} The value of the double field.
|
||||
* @return {number} The value of the signed 32-bit integer field.
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readSfixed32 = function() {
|
||||
goog.asserts.assert(
|
||||
@ -785,12 +816,27 @@ jspb.BinaryReader.prototype.readSfixed32 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed 32-bit fixed-length integer fiield from the binary stream, or
|
||||
* throws an error if the next field in the stream is not of the correct wire
|
||||
* type.
|
||||
*
|
||||
* @return {string} The value of the signed 32-bit integer field as a decimal
|
||||
* string.
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readSfixed32String = function() {
|
||||
goog.asserts.assert(
|
||||
this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
|
||||
return this.decoder_.readInt32().toString();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed 64-bit fixed-length integer fiield from the binary stream, or
|
||||
* throws an error if the next field in the stream is not of the correct wire
|
||||
* type.
|
||||
*
|
||||
* @return {number} The value of the float field.
|
||||
* @return {number} The value of the sfixed64 field.
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readSfixed64 = function() {
|
||||
goog.asserts.assert(
|
||||
@ -799,6 +845,22 @@ jspb.BinaryReader.prototype.readSfixed64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed 64-bit fixed-length integer fiield from the binary stream, or
|
||||
* throws an error if the next field in the stream is not of the correct wire
|
||||
* type.
|
||||
*
|
||||
* Returns the value as a string.
|
||||
*
|
||||
* @return {string} The value of the sfixed64 field as a decimal string.
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readSfixed64String = function() {
|
||||
goog.asserts.assert(
|
||||
this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
|
||||
return this.decoder_.readInt64String();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32-bit floating-point field from the binary stream, or throws an
|
||||
* error if the next field in the stream is not of the correct wire type.
|
||||
@ -1027,6 +1089,16 @@ jspb.BinaryReader.prototype.readPackedSint64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a packed sint64 field, which consists of a length header and a list of
|
||||
* zigzag varints. Returns a list of strings.
|
||||
* @return {!Array.<string>}
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readPackedSint64String = function() {
|
||||
return this.readPackedField_(this.decoder_.readZigzagVarint64String);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a packed fixed32 field, which consists of a length header and a list
|
||||
* of unsigned 32-bit ints.
|
||||
@ -1047,6 +1119,16 @@ jspb.BinaryReader.prototype.readPackedFixed64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a packed fixed64 field, which consists of a length header and a list
|
||||
* of unsigned 64-bit ints. Returns a list of strings.
|
||||
* @return {!Array.<number>}
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readPackedFixed64String = function() {
|
||||
return this.readPackedField_(this.decoder_.readUint64String);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a packed sfixed32 field, which consists of a length header and a list
|
||||
* of 32-bit ints.
|
||||
@ -1067,6 +1149,16 @@ jspb.BinaryReader.prototype.readPackedSfixed64 = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a packed sfixed64 field, which consists of a length header and a list
|
||||
* of 64-bit ints. Returns a list of strings.
|
||||
* @return {!Array.<string>}
|
||||
*/
|
||||
jspb.BinaryReader.prototype.readPackedSfixed64String = function() {
|
||||
return this.readPackedField_(this.decoder_.readInt64String);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a packed float field, which consists of a length header and a list of
|
||||
* floats.
|
||||
|
@ -617,6 +617,16 @@ jspb.utils.decimalStringToHash64 = function(dec) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a signed or unsigned decimal string into two 32-bit halves, and
|
||||
* stores them in the temp variables listed above.
|
||||
* @param {string} value The decimal string to convert.
|
||||
*/
|
||||
jspb.utils.splitDecimalString = function(value) {
|
||||
jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts an 8-character hash string into its hexadecimal representation.
|
||||
* @param {string} hash
|
||||
|
@ -434,6 +434,20 @@ jspb.BinaryWriter.prototype.writeZigzagVarint64_ = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a zigzag varint field to the buffer without range checking.
|
||||
* @param {number} field The field number.
|
||||
* @param {string?} value The value to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeZigzagVarint64String_ = function(
|
||||
field, value) {
|
||||
if (value == null) return;
|
||||
this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
|
||||
this.encoder_.writeZigzagVarint64String(value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an int32 field to the buffer. Numbers outside the range [-2^31,2^31)
|
||||
* will be truncated.
|
||||
@ -574,6 +588,20 @@ jspb.BinaryWriter.prototype.writeSint64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a sint64 field to the buffer. Numbers outside the range [-2^63,2^63)
|
||||
* will be truncated.
|
||||
* @param {number} field The field number.
|
||||
* @param {string?} value The decimal string to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeSint64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
|
||||
(value < jspb.BinaryConstants.TWO_TO_63));
|
||||
this.writeZigzagVarint64String_(field, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a fixed32 field to the buffer. Numbers outside the range [0,2^32)
|
||||
* will be truncated.
|
||||
@ -604,6 +632,19 @@ jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a fixed64 field (with value as a string) to the buffer.
|
||||
* @param {number} field The field number.
|
||||
* @param {string?} value The value to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeFixed64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
var num = jspb.arith.UInt64.fromString(value);
|
||||
this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
|
||||
this.encoder_.writeSplitFixed64(num.lo, num.hi);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a sfixed32 field to the buffer. Numbers outside the range
|
||||
* [-2^31,2^31) will be truncated.
|
||||
@ -634,6 +675,20 @@ jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a sfixed64 string field to the buffer. Numbers outside the range
|
||||
* [-2^63,2^63) will be truncated.
|
||||
* @param {number} field The field number.
|
||||
* @param {string?} value The value to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeSfixed64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
var num = jspb.arith.Int64.fromString(value);
|
||||
this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
|
||||
this.encoder_.writeSplitFixed64(num.lo, num.hi);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a single-precision floating point field to the buffer. Numbers
|
||||
* requiring more than 32 bits of precision will be truncated.
|
||||
@ -796,28 +851,11 @@ jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) {
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated varint field.
|
||||
* Writes an array of numbers to the buffer as a repeated 32-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_ =
|
||||
function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeUnsignedVarint32_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated varint field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ =
|
||||
function(field, value) {
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt32 = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeSignedVarint32_(field, value[i]);
|
||||
@ -825,81 +863,13 @@ jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated varint field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_ =
|
||||
function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeUnsignedVarint64_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated varint field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_ =
|
||||
function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeSignedVarint64_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated zigzag field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeZigzagVarint32_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated zigzag field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeZigzagVarint64_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated 32-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt32 =
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_;
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers formatted as strings to the buffer as a repeated
|
||||
* 32-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt32String =
|
||||
function(field, value) {
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt32String = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeInt32String(field, value[i]);
|
||||
@ -912,8 +882,12 @@ jspb.BinaryWriter.prototype.writeRepeatedInt32String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt64 =
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_;
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt64 = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeSignedVarint64_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -922,8 +896,7 @@ jspb.BinaryWriter.prototype.writeRepeatedInt64 =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt64String =
|
||||
function(field, value) {
|
||||
jspb.BinaryWriter.prototype.writeRepeatedInt64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeInt64String(field, value[i]);
|
||||
@ -937,8 +910,12 @@ jspb.BinaryWriter.prototype.writeRepeatedInt64String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint32 =
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_;
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint32 = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeUnsignedVarint32_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -947,8 +924,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint32 =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint32String =
|
||||
function(field, value) {
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint32String = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeUint32String(field, value[i]);
|
||||
@ -962,8 +938,12 @@ jspb.BinaryWriter.prototype.writeRepeatedUint32String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint64 =
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_;
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint64 = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeUnsignedVarint64_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -972,8 +952,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint64 =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint64String =
|
||||
function(field, value) {
|
||||
jspb.BinaryWriter.prototype.writeRepeatedUint64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeUint64String(field, value[i]);
|
||||
@ -986,8 +965,12 @@ jspb.BinaryWriter.prototype.writeRepeatedUint64String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSint32 =
|
||||
jspb.BinaryWriter.prototype.writeRepeatedZigzag32_;
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSint32 = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeZigzagVarint32_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -995,8 +978,25 @@ jspb.BinaryWriter.prototype.writeRepeatedSint32 =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSint64 =
|
||||
jspb.BinaryWriter.prototype.writeRepeatedZigzag_;
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSint64 = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeZigzagVarint64_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array numbers to the buffer as a repeated signed 64-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSint64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeZigzagVarint64String_(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -1027,6 +1027,21 @@ jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated fixed64 field. This
|
||||
* works for both signed and unsigned fixed64s.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of decimal strings to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedFixed64String = function(
|
||||
field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeFixed64String(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated sfixed32 field.
|
||||
* @param {number} field The field number.
|
||||
@ -1053,6 +1068,20 @@ jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of decimal strings to the buffer as a repeated sfixed64
|
||||
* field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of decimal strings to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeRepeatedSfixed64String = function(field, value) {
|
||||
if (value == null) return;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.writeSfixed64String(field, value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a repeated float field.
|
||||
* @param {number} field The field number.
|
||||
@ -1203,30 +1232,11 @@ jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed varint field.
|
||||
* Writes an array of numbers to the buffer as a packed 32-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ = function(
|
||||
field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeUnsignedVarint32(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed varint field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedSignedVarint32_ = function(
|
||||
field, value) {
|
||||
jspb.BinaryWriter.prototype.writePackedInt32 = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
@ -1236,81 +1246,6 @@ jspb.BinaryWriter.prototype.writePackedSignedVarint32_ = function(
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed varint field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_ = function(
|
||||
field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeUnsignedVarint64(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed varint field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedSignedVarint64_ = function(
|
||||
field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeSignedVarint64(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed zigzag field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedZigzag32_ = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeZigzagVarint32(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed zigzag field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
* @private
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedZigzag64_ = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeZigzagVarint64(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed 32-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedInt32 =
|
||||
jspb.BinaryWriter.prototype.writePackedSignedVarint32_;
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers represented as strings to the buffer as a packed
|
||||
* 32-bit int field.
|
||||
@ -1332,8 +1267,14 @@ jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedInt64 =
|
||||
jspb.BinaryWriter.prototype.writePackedSignedVarint64_;
|
||||
jspb.BinaryWriter.prototype.writePackedInt64 = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeSignedVarint64(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -1342,8 +1283,7 @@ jspb.BinaryWriter.prototype.writePackedInt64 =
|
||||
* @param {number} field
|
||||
* @param {?Array.<string>} value
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedInt64String =
|
||||
function(field, value) {
|
||||
jspb.BinaryWriter.prototype.writePackedInt64String = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
@ -1359,8 +1299,14 @@ jspb.BinaryWriter.prototype.writePackedInt64String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedUint32 =
|
||||
jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_;
|
||||
jspb.BinaryWriter.prototype.writePackedUint32 = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeUnsignedVarint32(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -1385,8 +1331,14 @@ jspb.BinaryWriter.prototype.writePackedUint32String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedUint64 =
|
||||
jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_;
|
||||
jspb.BinaryWriter.prototype.writePackedUint64 = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeUnsignedVarint64(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -1412,17 +1364,46 @@ jspb.BinaryWriter.prototype.writePackedUint64String =
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedSint32 =
|
||||
jspb.BinaryWriter.prototype.writePackedZigzag32_;
|
||||
jspb.BinaryWriter.prototype.writePackedSint32 = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeZigzagVarint32(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array numbers to the buffer as a packed signed 64-bit int field.
|
||||
* Writes an array of numbers to the buffer as a packed signed 64-bit int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<number>} value The array of ints to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedSint64 =
|
||||
jspb.BinaryWriter.prototype.writePackedZigzag64_;
|
||||
jspb.BinaryWriter.prototype.writePackedSint64 = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeZigzagVarint64(value[i]);
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of decimal strings to the buffer as a packed signed 64-bit
|
||||
* int field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of decimal strings to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedSint64String = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
var bookmark = this.beginDelimited_(field);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
// TODO(haberman): make lossless
|
||||
this.encoder_.writeZigzagVarint64(parseInt(value[i], 10));
|
||||
}
|
||||
this.endDelimited_(bookmark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -1455,6 +1436,23 @@ jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers represented as strings to the buffer as a packed
|
||||
* fixed64 field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of strings to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedFixed64String = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
|
||||
this.encoder_.writeUnsignedVarint32(value.length * 8);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var num = jspb.arith.UInt64.fromString(value[i]);
|
||||
this.encoder_.writeSplitFixed64(num.lo, num.hi);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed sfixed32 field.
|
||||
* @param {number} field The field number.
|
||||
@ -1485,6 +1483,21 @@ jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed sfixed64 field.
|
||||
* @param {number} field The field number.
|
||||
* @param {?Array.<string>} value The array of decimal strings to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writePackedSfixed64String = function(field, value) {
|
||||
if (value == null || !value.length) return;
|
||||
this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
|
||||
this.encoder_.writeUnsignedVarint32(value.length * 8);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
this.encoder_.writeInt64String(value[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an array of numbers to the buffer as a packed float field.
|
||||
* @param {number} field The field number.
|
||||
|
54
js/map.js
54
js/map.js
@ -130,6 +130,58 @@ jspb.Map.prototype.toArray = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the map formatted as an array of key-value pairs, suitable for the
|
||||
* toObject() form of a message.
|
||||
*
|
||||
* @param {boolean=} includeInstance Whether to include the JSPB instance for
|
||||
* transitional soy proto support: http://goto/soy-param-migration
|
||||
* @param {!function((boolean|undefined),!V):!Object=} valueToObject
|
||||
* The static toObject() method, if V is a message type.
|
||||
* @return {!Array<!Array<!Object>>}
|
||||
*/
|
||||
jspb.Map.prototype.toObject = function(includeInstance, valueToObject) {
|
||||
var rawArray = this.toArray();
|
||||
var entries = [];
|
||||
for (var i = 0; i < rawArray.length; i++) {
|
||||
var entry = this.map_[rawArray[i][0].toString()];
|
||||
this.wrapEntry_(entry);
|
||||
var valueWrapper = /** @type {!V|undefined} */ (entry.valueWrapper);
|
||||
if (valueWrapper) {
|
||||
goog.asserts.assert(valueToObject);
|
||||
entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]);
|
||||
} else {
|
||||
entries.push([entry.key, entry.value]);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Map from the given array of key-value pairs when the values are of
|
||||
* message type. The values in the array must match the format returned by their
|
||||
* message type's toObject() method.
|
||||
*
|
||||
* @template K, V
|
||||
* @param {!Array<!Array<!Object>>} entries
|
||||
* @param {!function(new:V)|function(new:V,?)} valueCtor
|
||||
* The constructor for type V.
|
||||
* @param {!function(!Object):V} valueFromObject
|
||||
* The fromObject function for type V.
|
||||
* @return {!jspb.Map<K, V>}
|
||||
*/
|
||||
jspb.Map.fromObject = function(entries, valueCtor, valueFromObject) {
|
||||
var result = new jspb.Map([], valueCtor);
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
var key = entries[i][0];
|
||||
var value = valueFromObject(entries[i][1]);
|
||||
result.set(key, value);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper: return an iterator over an array.
|
||||
* @template T
|
||||
@ -193,7 +245,7 @@ jspb.Map.prototype.del = function(key) {
|
||||
* to help out Angular 1.x users. Still evaluating whether this is the best
|
||||
* option.
|
||||
*
|
||||
* @return {!Array<K|V>}
|
||||
* @return {!Array<!Array<K|V>>}
|
||||
*/
|
||||
jspb.Map.prototype.getEntryList = function() {
|
||||
var entries = [];
|
||||
|
@ -262,6 +262,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exercises the lazy map<->underlying array sync.
|
||||
*/
|
||||
@ -290,12 +291,16 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
}
|
||||
|
||||
describe('mapsTest', function() {
|
||||
makeTests({
|
||||
constructor: proto.jspb.test.TestMapFields,
|
||||
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
|
||||
}, proto.jspb.test.MapValueMessage, "_Binary");
|
||||
makeTests({
|
||||
constructor: proto.jspb.test.TestMapFieldsNoBinary,
|
||||
deserializeBinary: null
|
||||
}, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary");
|
||||
makeTests(
|
||||
{
|
||||
constructor: proto.jspb.test.TestMapFields,
|
||||
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
|
||||
},
|
||||
proto.jspb.test.MapValueMessage, '_Binary');
|
||||
makeTests(
|
||||
{
|
||||
constructor: proto.jspb.test.TestMapFieldsNoBinary,
|
||||
deserializeBinary: null
|
||||
},
|
||||
proto.jspb.test.MapValueMessageNoBinary, '_NoBinary');
|
||||
});
|
||||
|
@ -550,11 +550,11 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
|
||||
jspb.Message.readBinaryExtension = function(msg, reader, extensions,
|
||||
getExtensionFn, setExtensionFn) {
|
||||
var binaryFieldInfo = extensions[reader.getFieldNumber()];
|
||||
var fieldInfo = binaryFieldInfo.fieldInfo;
|
||||
if (!binaryFieldInfo) {
|
||||
reader.skipField();
|
||||
return;
|
||||
}
|
||||
var fieldInfo = binaryFieldInfo.fieldInfo;
|
||||
if (!binaryFieldInfo.binaryReaderFn) {
|
||||
throw new Error('Deserializing extension whose generated code does not ' +
|
||||
'support binary format');
|
||||
@ -972,7 +972,8 @@ jspb.Message.wrapRepeatedField_ = function(msg, ctor, fieldNumber) {
|
||||
* Sets a proto field and syncs it to the backing array.
|
||||
* @param {!jspb.Message} msg A jspb proto.
|
||||
* @param {number} fieldNumber The field number.
|
||||
* @param {jspb.Message|undefined} value A new value for this proto field.
|
||||
* @param {?jspb.Message|?jspb.Map|undefined} value A new value for this proto
|
||||
* field.
|
||||
* @protected
|
||||
*/
|
||||
jspb.Message.setWrapperField = function(msg, fieldNumber, value) {
|
||||
|
@ -73,10 +73,12 @@ goog.require('proto.jspb.test.TestGroup1');
|
||||
goog.require('proto.jspb.test.TestMessageWithOneof');
|
||||
goog.require('proto.jspb.test.TestReservedNames');
|
||||
goog.require('proto.jspb.test.TestReservedNamesExtension');
|
||||
goog.require('proto.jspb.test.Deeply.Nested.Message');
|
||||
|
||||
// CommonJS-LoadFromFile: test2_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.ExtensionMessage');
|
||||
goog.require('proto.jspb.test.TestExtensionsMessage');
|
||||
goog.require('proto.jspb.test.ForeignNestedFieldMessage');
|
||||
|
||||
|
||||
|
||||
@ -1050,8 +1052,10 @@ describe('Message test suite', function() {
|
||||
|
||||
// After a serialization-deserialization round trip we should get back the
|
||||
// same data we started with.
|
||||
var serialized = msg.serializeBinary();
|
||||
var deserialized = proto.jspb.test.ForeignNestedFieldMessage.deserializeBinary(serialized);
|
||||
var serialized = msg.toObject();
|
||||
var deserialized =
|
||||
proto.jspb.test.ForeignNestedFieldMessage.fromObject(serialized);
|
||||
assertEquals(5, deserialized.getDeeplyNestedMessage().getCount());
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -38,6 +38,12 @@ goog.require('proto.jspb.test.ForeignMessage');
|
||||
goog.require('proto.jspb.test.Proto3Enum');
|
||||
goog.require('proto.jspb.test.TestProto3');
|
||||
|
||||
// CommonJS-LoadFromFile: google/protobuf/timestamp_pb proto.google.protobuf
|
||||
goog.require('proto.google.protobuf.Timestamp');
|
||||
|
||||
// CommonJS-LoadFromFile: google/protobuf/struct_pb proto.google.protobuf
|
||||
goog.require('proto.google.protobuf.Struct');
|
||||
|
||||
|
||||
var BYTES = new Uint8Array([1, 2, 8, 9]);
|
||||
var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
|
||||
@ -326,4 +332,36 @@ describe('proto3Test', function() {
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
});
|
||||
|
||||
it('testTimestampWellKnownType', function() {
|
||||
var msg = new proto.google.protobuf.Timestamp();
|
||||
msg.fromDate(new Date(123456789));
|
||||
assertEquals(123456, msg.getSeconds());
|
||||
assertEquals(789000000, msg.getNanos());
|
||||
var date = msg.toDate();
|
||||
assertEquals(123456789, date.getTime());
|
||||
});
|
||||
|
||||
it('testStructWellKnownType', function() {
|
||||
var jsObj = {
|
||||
abc: "def",
|
||||
number: 12345.678,
|
||||
nullKey: null,
|
||||
boolKey: true,
|
||||
listKey: [1, null, true, false, "abc"],
|
||||
structKey: {foo: "bar", somenum: 123},
|
||||
complicatedKey: [{xyz: {abc: [3, 4, null, false]}}, "zzz"]
|
||||
};
|
||||
|
||||
var struct = proto.google.protobuf.Struct.fromJavaScript(jsObj);
|
||||
var jsObj2 = struct.toJavaScript();
|
||||
|
||||
assertEquals("def", jsObj2.abc);
|
||||
assertEquals(12345.678, jsObj2.number);
|
||||
assertEquals(null, jsObj2.nullKey);
|
||||
assertEquals(true, jsObj2.boolKey);
|
||||
assertEquals("abc", jsObj2.listKey[4]);
|
||||
assertEquals("bar", jsObj2.structKey.foo);
|
||||
assertEquals(4, jsObj2.complicatedKey[0].xyz.abc[1]);
|
||||
});
|
||||
});
|
||||
|
@ -234,7 +234,9 @@ message TestEndsWithBytes {
|
||||
optional bytes data = 2;
|
||||
}
|
||||
|
||||
|
||||
message TestMapFieldsNoBinary {
|
||||
|
||||
map<string, string> map_string_string = 1;
|
||||
map<string, int32> map_string_int32 = 2;
|
||||
map<string, int64> map_string_int64 = 3;
|
||||
@ -252,12 +254,13 @@ message TestMapFieldsNoBinary {
|
||||
}
|
||||
|
||||
enum MapValueEnumNoBinary {
|
||||
MAP_VALUE_FOO_NOBINARY = 0;
|
||||
MAP_VALUE_BAR_NOBINARY = 1;
|
||||
MAP_VALUE_BAZ_NOBINARY = 2;
|
||||
MAP_VALUE_FOO = 0;
|
||||
MAP_VALUE_BAR = 1;
|
||||
MAP_VALUE_BAZ = 2;
|
||||
}
|
||||
|
||||
message MapValueMessageNoBinary {
|
||||
|
||||
optional int32 foo = 1;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
|
||||
|
||||
def _GetPath(ctx, path):
|
||||
if ctx.label.workspace_root:
|
||||
return ctx.label.workspace_root + '/' + path
|
||||
@ -230,7 +228,6 @@ def cc_proto_library(
|
||||
includes=includes,
|
||||
**kargs)
|
||||
|
||||
|
||||
def internal_gen_well_known_protos_java(srcs):
|
||||
"""Bazel rule to generate the gen_well_known_protos_java genrule
|
||||
|
||||
@ -254,7 +251,6 @@ def internal_gen_well_known_protos_java(srcs):
|
||||
tools = [":protoc"],
|
||||
)
|
||||
|
||||
|
||||
def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
|
||||
"""Macro to copy files to a different directory and then create a filegroup.
|
||||
|
||||
@ -284,7 +280,6 @@ def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
|
||||
srcs = outs,
|
||||
**kwargs)
|
||||
|
||||
|
||||
def py_proto_library(
|
||||
name,
|
||||
srcs=[],
|
||||
|
@ -57,6 +57,8 @@ directly instead of this class.
|
||||
|
||||
__author__ = 'matthewtoia@google.com (Matt Toia)'
|
||||
|
||||
import collections
|
||||
|
||||
from google.protobuf import descriptor
|
||||
from google.protobuf import descriptor_database
|
||||
from google.protobuf import text_encoding
|
||||
@ -88,6 +90,14 @@ def _OptionsOrNone(descriptor_proto):
|
||||
return None
|
||||
|
||||
|
||||
def _IsMessageSetExtension(field):
|
||||
return (field.is_extension and
|
||||
field.containing_type.has_options and
|
||||
field.containing_type.GetOptions().message_set_wire_format and
|
||||
field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
|
||||
field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL)
|
||||
|
||||
|
||||
class DescriptorPool(object):
|
||||
"""A collection of protobufs dynamically constructed by descriptor protos."""
|
||||
|
||||
@ -115,6 +125,12 @@ class DescriptorPool(object):
|
||||
self._descriptors = {}
|
||||
self._enum_descriptors = {}
|
||||
self._file_descriptors = {}
|
||||
self._toplevel_extensions = {}
|
||||
# We store extensions in two two-level mappings: The first key is the
|
||||
# descriptor of the message being extended, the second key is the extension
|
||||
# full name or its tag number.
|
||||
self._extensions_by_name = collections.defaultdict(dict)
|
||||
self._extensions_by_number = collections.defaultdict(dict)
|
||||
|
||||
def Add(self, file_desc_proto):
|
||||
"""Adds the FileDescriptorProto and its types to this pool.
|
||||
@ -170,6 +186,48 @@ class DescriptorPool(object):
|
||||
self._enum_descriptors[enum_desc.full_name] = enum_desc
|
||||
self.AddFileDescriptor(enum_desc.file)
|
||||
|
||||
def AddExtensionDescriptor(self, extension):
|
||||
"""Adds a FieldDescriptor describing an extension to the pool.
|
||||
|
||||
Args:
|
||||
extension: A FieldDescriptor.
|
||||
|
||||
Raises:
|
||||
AssertionError: when another extension with the same number extends the
|
||||
same message.
|
||||
TypeError: when the specified extension is not a
|
||||
descriptor.FieldDescriptor.
|
||||
"""
|
||||
if not (isinstance(extension, descriptor.FieldDescriptor) and
|
||||
extension.is_extension):
|
||||
raise TypeError('Expected an extension descriptor.')
|
||||
|
||||
if extension.extension_scope is None:
|
||||
self._toplevel_extensions[extension.full_name] = extension
|
||||
|
||||
try:
|
||||
existing_desc = self._extensions_by_number[
|
||||
extension.containing_type][extension.number]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
if extension is not existing_desc:
|
||||
raise AssertionError(
|
||||
'Extensions "%s" and "%s" both try to extend message type "%s" '
|
||||
'with field number %d.' %
|
||||
(extension.full_name, existing_desc.full_name,
|
||||
extension.containing_type.full_name, extension.number))
|
||||
|
||||
self._extensions_by_number[extension.containing_type][
|
||||
extension.number] = extension
|
||||
self._extensions_by_name[extension.containing_type][
|
||||
extension.full_name] = extension
|
||||
|
||||
# Also register MessageSet extensions with the type name.
|
||||
if _IsMessageSetExtension(extension):
|
||||
self._extensions_by_name[extension.containing_type][
|
||||
extension.message_type.full_name] = extension
|
||||
|
||||
def AddFileDescriptor(self, file_desc):
|
||||
"""Adds a FileDescriptor to the pool, non-recursively.
|
||||
|
||||
@ -302,6 +360,14 @@ class DescriptorPool(object):
|
||||
A FieldDescriptor, describing the named extension.
|
||||
"""
|
||||
full_name = _NormalizeFullyQualifiedName(full_name)
|
||||
try:
|
||||
# The proto compiler does not give any link between the FileDescriptor
|
||||
# and top-level extensions unless the FileDescriptorProto is added to
|
||||
# the DescriptorDatabase, but this can impact memory usage.
|
||||
# So we registered these extensions by name explicitly.
|
||||
return self._toplevel_extensions[full_name]
|
||||
except KeyError:
|
||||
pass
|
||||
message_name, _, extension_name = full_name.rpartition('.')
|
||||
try:
|
||||
# Most extensions are nested inside a message.
|
||||
@ -311,6 +377,39 @@ class DescriptorPool(object):
|
||||
scope = self.FindFileContainingSymbol(full_name)
|
||||
return scope.extensions_by_name[extension_name]
|
||||
|
||||
def FindExtensionByNumber(self, message_descriptor, number):
|
||||
"""Gets the extension of the specified message with the specified number.
|
||||
|
||||
Extensions have to be registered to this pool by calling
|
||||
AddExtensionDescriptor.
|
||||
|
||||
Args:
|
||||
message_descriptor: descriptor of the extended message.
|
||||
number: integer, number of the extension field.
|
||||
|
||||
Returns:
|
||||
A FieldDescriptor describing the extension.
|
||||
|
||||
Raise:
|
||||
KeyError: when no extension with the given number is known for the
|
||||
specified message.
|
||||
"""
|
||||
return self._extensions_by_number[message_descriptor][number]
|
||||
|
||||
def FindAllExtensions(self, message_descriptor):
|
||||
"""Gets all the known extension of a given message.
|
||||
|
||||
Extensions have to be registered to this pool by calling
|
||||
AddExtensionDescriptor.
|
||||
|
||||
Args:
|
||||
message_descriptor: descriptor of the extended message.
|
||||
|
||||
Returns:
|
||||
A list of FieldDescriptor describing the extensions.
|
||||
"""
|
||||
return self._extensions_by_number[message_descriptor].values()
|
||||
|
||||
def _ConvertFileProtoToFileDescriptor(self, file_proto):
|
||||
"""Creates a FileDescriptor from a proto or returns a cached copy.
|
||||
|
||||
|
@ -642,10 +642,10 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
|
||||
|
||||
MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP)
|
||||
|
||||
def MessageSetItemDecoder(extensions_by_number):
|
||||
def MessageSetItemDecoder(descriptor):
|
||||
"""Returns a decoder for a MessageSet item.
|
||||
|
||||
The parameter is the _extensions_by_number map for the message class.
|
||||
The parameter is the message Descriptor.
|
||||
|
||||
The message set message looks like this:
|
||||
message MessageSet {
|
||||
@ -694,7 +694,7 @@ def MessageSetItemDecoder(extensions_by_number):
|
||||
if message_start == -1:
|
||||
raise _DecodeError('MessageSet item missing message.')
|
||||
|
||||
extension = extensions_by_number.get(type_id)
|
||||
extension = message.Extensions._FindExtensionByNumber(type_id)
|
||||
if extension is not None:
|
||||
value = field_dict.get(extension)
|
||||
if value is None:
|
||||
|
@ -254,6 +254,53 @@ class DescriptorPoolTest(unittest.TestCase):
|
||||
with self.assertRaises(KeyError):
|
||||
self.pool.FindFieldByName('Does not exist')
|
||||
|
||||
def testFindAllExtensions(self):
|
||||
factory1_message = self.pool.FindMessageTypeByName(
|
||||
'google.protobuf.python.internal.Factory1Message')
|
||||
factory2_message = self.pool.FindMessageTypeByName(
|
||||
'google.protobuf.python.internal.Factory2Message')
|
||||
# An extension defined in a message.
|
||||
one_more_field = factory2_message.extensions_by_name['one_more_field']
|
||||
self.pool.AddExtensionDescriptor(one_more_field)
|
||||
# An extension defined at file scope.
|
||||
factory_test2 = self.pool.FindFileByName(
|
||||
'google/protobuf/internal/factory_test2.proto')
|
||||
another_field = factory_test2.extensions_by_name['another_field']
|
||||
self.pool.AddExtensionDescriptor(another_field)
|
||||
|
||||
extensions = self.pool.FindAllExtensions(factory1_message)
|
||||
expected_extension_numbers = {one_more_field, another_field}
|
||||
self.assertEqual(expected_extension_numbers, set(extensions))
|
||||
# Verify that mutating the returned list does not affect the pool.
|
||||
extensions.append('unexpected_element')
|
||||
# Get the extensions again, the returned value does not contain the
|
||||
# 'unexpected_element'.
|
||||
extensions = self.pool.FindAllExtensions(factory1_message)
|
||||
self.assertEqual(expected_extension_numbers, set(extensions))
|
||||
|
||||
def testFindExtensionByNumber(self):
|
||||
factory1_message = self.pool.FindMessageTypeByName(
|
||||
'google.protobuf.python.internal.Factory1Message')
|
||||
factory2_message = self.pool.FindMessageTypeByName(
|
||||
'google.protobuf.python.internal.Factory2Message')
|
||||
# An extension defined in a message.
|
||||
one_more_field = factory2_message.extensions_by_name['one_more_field']
|
||||
self.pool.AddExtensionDescriptor(one_more_field)
|
||||
# An extension defined at file scope.
|
||||
factory_test2 = self.pool.FindFileByName(
|
||||
'google/protobuf/internal/factory_test2.proto')
|
||||
another_field = factory_test2.extensions_by_name['another_field']
|
||||
self.pool.AddExtensionDescriptor(another_field)
|
||||
|
||||
# An extension defined in a message.
|
||||
extension = self.pool.FindExtensionByNumber(factory1_message, 1001)
|
||||
self.assertEqual(extension.name, 'one_more_field')
|
||||
# An extension defined at file scope.
|
||||
extension = self.pool.FindExtensionByNumber(factory1_message, 1002)
|
||||
self.assertEqual(extension.name, 'another_field')
|
||||
with self.assertRaises(KeyError):
|
||||
extension = self.pool.FindExtensionByNumber(factory1_message, 1234567)
|
||||
|
||||
def testExtensionsAreNotFields(self):
|
||||
with self.assertRaises(KeyError):
|
||||
self.pool.FindFieldByName('google.protobuf.python.internal.another_field')
|
||||
|
@ -114,18 +114,18 @@ class MessageFactoryTest(unittest.TestCase):
|
||||
).issubset(set(messages.keys())))
|
||||
self._ExerciseDynamicClass(
|
||||
messages['google.protobuf.python.internal.Factory2Message'])
|
||||
self.assertTrue(
|
||||
set(['google.protobuf.python.internal.Factory2Message.one_more_field',
|
||||
'google.protobuf.python.internal.another_field'],
|
||||
).issubset(
|
||||
set(messages['google.protobuf.python.internal.Factory1Message']
|
||||
._extensions_by_name.keys())))
|
||||
factory_msg1 = messages['google.protobuf.python.internal.Factory1Message']
|
||||
self.assertTrue(set(
|
||||
['google.protobuf.python.internal.Factory2Message.one_more_field',
|
||||
'google.protobuf.python.internal.another_field'],).issubset(set(
|
||||
ext.full_name
|
||||
for ext in factory_msg1.DESCRIPTOR.file.pool.FindAllExtensions(
|
||||
factory_msg1.DESCRIPTOR))))
|
||||
msg1 = messages['google.protobuf.python.internal.Factory1Message']()
|
||||
ext1 = factory_msg1._extensions_by_name[
|
||||
'google.protobuf.python.internal.Factory2Message.one_more_field']
|
||||
ext2 = factory_msg1._extensions_by_name[
|
||||
'google.protobuf.python.internal.another_field']
|
||||
ext1 = msg1.Extensions._FindExtensionByName(
|
||||
'google.protobuf.python.internal.Factory2Message.one_more_field')
|
||||
ext2 = msg1.Extensions._FindExtensionByName(
|
||||
'google.protobuf.python.internal.another_field')
|
||||
msg1.Extensions[ext1] = 'test1'
|
||||
msg1.Extensions[ext2] = 'test2'
|
||||
self.assertEqual('test1', msg1.Extensions[ext1])
|
||||
|
@ -51,8 +51,8 @@ this file*.
|
||||
__author__ = 'robinson@google.com (Will Robinson)'
|
||||
|
||||
from io import BytesIO
|
||||
import sys
|
||||
import struct
|
||||
import sys
|
||||
import weakref
|
||||
|
||||
import six
|
||||
@ -162,12 +162,10 @@ class GeneratedProtocolMessageType(type):
|
||||
"""
|
||||
descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
|
||||
cls._decoders_by_tag = {}
|
||||
cls._extensions_by_name = {}
|
||||
cls._extensions_by_number = {}
|
||||
if (descriptor.has_options and
|
||||
descriptor.GetOptions().message_set_wire_format):
|
||||
cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
|
||||
decoder.MessageSetItemDecoder(cls._extensions_by_number), None)
|
||||
decoder.MessageSetItemDecoder(descriptor), None)
|
||||
|
||||
# Attach stuff to each FieldDescriptor for quick lookup later on.
|
||||
for field in descriptor.fields:
|
||||
@ -747,32 +745,21 @@ def _AddPropertiesForExtensions(descriptor, cls):
|
||||
constant_name = extension_name.upper() + "_FIELD_NUMBER"
|
||||
setattr(cls, constant_name, extension_field.number)
|
||||
|
||||
# TODO(amauryfa): Migrate all users of these attributes to functions like
|
||||
# pool.FindExtensionByNumber(descriptor).
|
||||
if descriptor.file is not None:
|
||||
# TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available.
|
||||
pool = descriptor.file.pool
|
||||
cls._extensions_by_number = pool._extensions_by_number[descriptor]
|
||||
cls._extensions_by_name = pool._extensions_by_name[descriptor]
|
||||
|
||||
def _AddStaticMethods(cls):
|
||||
# TODO(robinson): This probably needs to be thread-safe(?)
|
||||
def RegisterExtension(extension_handle):
|
||||
extension_handle.containing_type = cls.DESCRIPTOR
|
||||
# TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available.
|
||||
cls.DESCRIPTOR.file.pool.AddExtensionDescriptor(extension_handle)
|
||||
_AttachFieldHelpers(cls, extension_handle)
|
||||
|
||||
# Try to insert our extension, failing if an extension with the same number
|
||||
# already exists.
|
||||
actual_handle = cls._extensions_by_number.setdefault(
|
||||
extension_handle.number, extension_handle)
|
||||
if actual_handle is not extension_handle:
|
||||
raise AssertionError(
|
||||
'Extensions "%s" and "%s" both try to extend message type "%s" with '
|
||||
'field number %d.' %
|
||||
(extension_handle.full_name, actual_handle.full_name,
|
||||
cls.DESCRIPTOR.full_name, extension_handle.number))
|
||||
|
||||
cls._extensions_by_name[extension_handle.full_name] = extension_handle
|
||||
|
||||
handle = extension_handle # avoid line wrapping
|
||||
if _IsMessageSetExtension(handle):
|
||||
# MessageSet extension. Also register under type name.
|
||||
cls._extensions_by_name[
|
||||
extension_handle.message_type.full_name] = extension_handle
|
||||
|
||||
cls.RegisterExtension = staticmethod(RegisterExtension)
|
||||
|
||||
def FromString(s):
|
||||
@ -1230,7 +1217,7 @@ def _AddMergeFromMethod(cls):
|
||||
if not isinstance(msg, cls):
|
||||
raise TypeError(
|
||||
"Parameter to MergeFrom() must be instance of same class: "
|
||||
"expected %s got %s." % (cls.__name__, type(msg).__name__))
|
||||
'expected %s got %s.' % (cls.__name__, msg.__class__.__name__))
|
||||
|
||||
assert msg is not self
|
||||
self._Modified()
|
||||
|
@ -99,12 +99,12 @@ class _MiniDecoder(object):
|
||||
return wire_format.UnpackTag(self.ReadVarint())
|
||||
|
||||
def ReadFloat(self):
|
||||
result = struct.unpack("<f", self._bytes[self._pos:self._pos+4])[0]
|
||||
result = struct.unpack('<f', self._bytes[self._pos:self._pos+4])[0]
|
||||
self._pos += 4
|
||||
return result
|
||||
|
||||
def ReadDouble(self):
|
||||
result = struct.unpack("<d", self._bytes[self._pos:self._pos+8])[0]
|
||||
result = struct.unpack('<d', self._bytes[self._pos:self._pos+8])[0]
|
||||
self._pos += 8
|
||||
return result
|
||||
|
||||
@ -621,9 +621,15 @@ class ReflectionTest(BaseTestCase):
|
||||
self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
|
||||
self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
|
||||
|
||||
def testIntegerTypes(self):
|
||||
def assertIntegerTypes(self, integer_fn):
|
||||
"""Verifies setting of scalar integers.
|
||||
|
||||
Args:
|
||||
integer_fn: A function to wrap the integers that will be assigned.
|
||||
"""
|
||||
def TestGetAndDeserialize(field_name, value, expected_type):
|
||||
proto = unittest_pb2.TestAllTypes()
|
||||
value = integer_fn(value)
|
||||
setattr(proto, field_name, value)
|
||||
self.assertIsInstance(getattr(proto, field_name), expected_type)
|
||||
proto2 = unittest_pb2.TestAllTypes()
|
||||
@ -635,7 +641,7 @@ class ReflectionTest(BaseTestCase):
|
||||
TestGetAndDeserialize('optional_uint32', 1 << 30, int)
|
||||
try:
|
||||
integer_64 = long
|
||||
except NameError: # Python3
|
||||
except NameError: # Python3
|
||||
integer_64 = int
|
||||
if struct.calcsize('L') == 4:
|
||||
# Python only has signed ints, so 32-bit python can't fit an uint32
|
||||
@ -649,9 +655,33 @@ class ReflectionTest(BaseTestCase):
|
||||
TestGetAndDeserialize('optional_uint64', 1 << 30, integer_64)
|
||||
TestGetAndDeserialize('optional_uint64', 1 << 60, integer_64)
|
||||
|
||||
def testSingleScalarBoundsChecking(self):
|
||||
def testIntegerTypes(self):
|
||||
self.assertIntegerTypes(lambda x: x)
|
||||
|
||||
def testNonStandardIntegerTypes(self):
|
||||
self.assertIntegerTypes(test_util.NonStandardInteger)
|
||||
|
||||
def testIllegalValuesForIntegers(self):
|
||||
pb = unittest_pb2.TestAllTypes()
|
||||
|
||||
# Strings are illegal, even when the represent an integer.
|
||||
with self.assertRaises(TypeError):
|
||||
pb.optional_uint64 = '2'
|
||||
|
||||
# The exact error should propagate with a poorly written custom integer.
|
||||
with self.assertRaisesRegexp(RuntimeError, 'my_error'):
|
||||
pb.optional_uint64 = test_util.NonStandardInteger(5, 'my_error')
|
||||
|
||||
def assetIntegerBoundsChecking(self, integer_fn):
|
||||
"""Verifies bounds checking for scalar integer fields.
|
||||
|
||||
Args:
|
||||
integer_fn: A function to wrap the integers that will be assigned.
|
||||
"""
|
||||
def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
|
||||
pb = unittest_pb2.TestAllTypes()
|
||||
expected_min = integer_fn(expected_min)
|
||||
expected_max = integer_fn(expected_max)
|
||||
setattr(pb, field_name, expected_min)
|
||||
self.assertEqual(expected_min, getattr(pb, field_name))
|
||||
setattr(pb, field_name, expected_max)
|
||||
@ -663,11 +693,22 @@ class ReflectionTest(BaseTestCase):
|
||||
TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff)
|
||||
TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1)
|
||||
TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff)
|
||||
# A bit of white-box testing since -1 is an int and not a long in C++ and
|
||||
# so goes down a different path.
|
||||
pb = unittest_pb2.TestAllTypes()
|
||||
with self.assertRaises(ValueError):
|
||||
pb.optional_uint64 = integer_fn(-(1 << 63))
|
||||
|
||||
pb = unittest_pb2.TestAllTypes()
|
||||
pb.optional_nested_enum = 1
|
||||
pb.optional_nested_enum = integer_fn(1)
|
||||
self.assertEqual(1, pb.optional_nested_enum)
|
||||
|
||||
def testSingleScalarBoundsChecking(self):
|
||||
self.assetIntegerBoundsChecking(lambda x: x)
|
||||
|
||||
def testNonStandardSingleScalarBoundsChecking(self):
|
||||
self.assetIntegerBoundsChecking(test_util.NonStandardInteger)
|
||||
|
||||
def testRepeatedScalarTypeSafety(self):
|
||||
proto = unittest_pb2.TestAllTypes()
|
||||
self.assertRaises(TypeError, proto.repeated_int32.append, 1.1)
|
||||
@ -1187,12 +1228,18 @@ class ReflectionTest(BaseTestCase):
|
||||
self.assertTrue(not extendee_proto.HasExtension(extension))
|
||||
|
||||
def testRegisteredExtensions(self):
|
||||
self.assertTrue('protobuf_unittest.optional_int32_extension' in
|
||||
unittest_pb2.TestAllExtensions._extensions_by_name)
|
||||
self.assertTrue(1 in unittest_pb2.TestAllExtensions._extensions_by_number)
|
||||
pool = unittest_pb2.DESCRIPTOR.pool
|
||||
self.assertTrue(
|
||||
pool.FindExtensionByNumber(
|
||||
unittest_pb2.TestAllExtensions.DESCRIPTOR, 1))
|
||||
self.assertIs(
|
||||
pool.FindExtensionByName(
|
||||
'protobuf_unittest.optional_int32_extension').containing_type,
|
||||
unittest_pb2.TestAllExtensions.DESCRIPTOR)
|
||||
# Make sure extensions haven't been registered into types that shouldn't
|
||||
# have any.
|
||||
self.assertEqual(0, len(unittest_pb2.TestAllTypes._extensions_by_name))
|
||||
self.assertEqual(0, len(
|
||||
pool.FindAllExtensions(unittest_pb2.TestAllTypes.DESCRIPTOR)))
|
||||
|
||||
# If message A directly contains message B, and
|
||||
# a.HasField('b') is currently False, then mutating any
|
||||
|
@ -36,8 +36,9 @@ This is intentionally modeled on C++ code in
|
||||
|
||||
__author__ = 'robinson@google.com (Will Robinson)'
|
||||
|
||||
import numbers
|
||||
import operator
|
||||
import os.path
|
||||
|
||||
import sys
|
||||
|
||||
from google.protobuf import unittest_import_pb2
|
||||
@ -694,3 +695,154 @@ def SetAllUnpackedFields(message):
|
||||
message.unpacked_bool.extend([True, False])
|
||||
message.unpacked_enum.extend([unittest_pb2.FOREIGN_BAR,
|
||||
unittest_pb2.FOREIGN_BAZ])
|
||||
|
||||
|
||||
class NonStandardInteger(numbers.Integral):
|
||||
"""An integer object that does not subclass int.
|
||||
|
||||
This is used to verify that both C++ and regular proto systems can handle
|
||||
integer others than int and long and that they handle them in predictable
|
||||
ways.
|
||||
|
||||
NonStandardInteger is the minimal legal specification for a custom Integral.
|
||||
As such, it does not support 0 < x < 5 and it is not hashable.
|
||||
|
||||
Note: This is added here instead of relying on numpy or a similar library with
|
||||
custom integers to limit dependencies.
|
||||
"""
|
||||
|
||||
def __init__(self, val, error_string_on_conversion=None):
|
||||
assert isinstance(val, numbers.Integral)
|
||||
if isinstance(val, NonStandardInteger):
|
||||
val = val.val
|
||||
self.val = val
|
||||
self.error_string_on_conversion = error_string_on_conversion
|
||||
|
||||
def __long__(self):
|
||||
if self.error_string_on_conversion:
|
||||
raise RuntimeError(self.error_string_on_conversion)
|
||||
return long(self.val)
|
||||
|
||||
def __abs__(self):
|
||||
return NonStandardInteger(operator.abs(self.val))
|
||||
|
||||
def __add__(self, y):
|
||||
return NonStandardInteger(operator.add(self.val, y))
|
||||
|
||||
def __div__(self, y):
|
||||
return NonStandardInteger(operator.div(self.val, y))
|
||||
|
||||
def __eq__(self, y):
|
||||
return operator.eq(self.val, y)
|
||||
|
||||
def __floordiv__(self, y):
|
||||
return NonStandardInteger(operator.floordiv(self.val, y))
|
||||
|
||||
def __truediv__(self, y):
|
||||
return NonStandardInteger(operator.truediv(self.val, y))
|
||||
|
||||
def __invert__(self):
|
||||
return NonStandardInteger(operator.invert(self.val))
|
||||
|
||||
def __mod__(self, y):
|
||||
return NonStandardInteger(operator.mod(self.val, y))
|
||||
|
||||
def __mul__(self, y):
|
||||
return NonStandardInteger(operator.mul(self.val, y))
|
||||
|
||||
def __neg__(self):
|
||||
return NonStandardInteger(operator.neg(self.val))
|
||||
|
||||
def __pos__(self):
|
||||
return NonStandardInteger(operator.pos(self.val))
|
||||
|
||||
def __pow__(self, y):
|
||||
return NonStandardInteger(operator.pow(self.val, y))
|
||||
|
||||
def __trunc__(self):
|
||||
return int(self.val)
|
||||
|
||||
def __radd__(self, y):
|
||||
return NonStandardInteger(operator.add(y, self.val))
|
||||
|
||||
def __rdiv__(self, y):
|
||||
return NonStandardInteger(operator.div(y, self.val))
|
||||
|
||||
def __rmod__(self, y):
|
||||
return NonStandardInteger(operator.mod(y, self.val))
|
||||
|
||||
def __rmul__(self, y):
|
||||
return NonStandardInteger(operator.mul(y, self.val))
|
||||
|
||||
def __rpow__(self, y):
|
||||
return NonStandardInteger(operator.pow(y, self.val))
|
||||
|
||||
def __rfloordiv__(self, y):
|
||||
return NonStandardInteger(operator.floordiv(y, self.val))
|
||||
|
||||
def __rtruediv__(self, y):
|
||||
return NonStandardInteger(operator.truediv(y, self.val))
|
||||
|
||||
def __lshift__(self, y):
|
||||
return NonStandardInteger(operator.lshift(self.val, y))
|
||||
|
||||
def __rshift__(self, y):
|
||||
return NonStandardInteger(operator.rshift(self.val, y))
|
||||
|
||||
def __rlshift__(self, y):
|
||||
return NonStandardInteger(operator.lshift(y, self.val))
|
||||
|
||||
def __rrshift__(self, y):
|
||||
return NonStandardInteger(operator.rshift(y, self.val))
|
||||
|
||||
def __le__(self, y):
|
||||
if isinstance(y, NonStandardInteger):
|
||||
y = y.val
|
||||
return operator.le(self.val, y)
|
||||
|
||||
def __lt__(self, y):
|
||||
if isinstance(y, NonStandardInteger):
|
||||
y = y.val
|
||||
return operator.lt(self.val, y)
|
||||
|
||||
def __and__(self, y):
|
||||
return NonStandardInteger(operator.and_(self.val, y))
|
||||
|
||||
def __or__(self, y):
|
||||
return NonStandardInteger(operator.or_(self.val, y))
|
||||
|
||||
def __xor__(self, y):
|
||||
return NonStandardInteger(operator.xor(self.val, y))
|
||||
|
||||
def __rand__(self, y):
|
||||
return NonStandardInteger(operator.and_(y, self.val))
|
||||
|
||||
def __ror__(self, y):
|
||||
return NonStandardInteger(operator.or_(y, self.val))
|
||||
|
||||
def __rxor__(self, y):
|
||||
return NonStandardInteger(operator.xor(y, self.val))
|
||||
|
||||
def __bool__(self):
|
||||
return self.val
|
||||
|
||||
def __nonzero__(self):
|
||||
return self.val
|
||||
|
||||
def __ceil__(self):
|
||||
return self
|
||||
|
||||
def __floor__(self):
|
||||
return self
|
||||
|
||||
def __int__(self):
|
||||
if self.error_string_on_conversion:
|
||||
raise RuntimeError(self.error_string_on_conversion)
|
||||
return int(self.val)
|
||||
|
||||
def __round__(self):
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
return 'NonStandardInteger(%s)' % self.val
|
||||
|
||||
|
@ -124,5 +124,3 @@ else:
|
||||
def Same(func):
|
||||
return func
|
||||
return Same
|
||||
|
||||
|
||||
|
@ -582,22 +582,20 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
|
||||
% (letter,) for letter in string.ascii_uppercase))
|
||||
self.CompareToGoldenText(text_format.MessageToString(message), golden)
|
||||
|
||||
def testMapOrderSemantics(self):
|
||||
golden_lines = self.ReadGolden('map_test_data.txt')
|
||||
# The C++ implementation emits defaulted-value fields, while the Python
|
||||
# implementation does not. Adjusting for this is awkward, but it is
|
||||
# valuable to test against a common golden file.
|
||||
line_blacklist = (' key: 0\n', ' value: 0\n', ' key: false\n',
|
||||
' value: false\n')
|
||||
golden_lines = [line for line in golden_lines if line not in line_blacklist]
|
||||
# TODO(teboring): In c/137553523, not serializing default value for map entry
|
||||
# message has been fixed. This test needs to be disabled in order to submit
|
||||
# that cl. Add this back when c/137553523 has been submitted.
|
||||
# def testMapOrderSemantics(self):
|
||||
# golden_lines = self.ReadGolden('map_test_data.txt')
|
||||
|
||||
message = map_unittest_pb2.TestMap()
|
||||
text_format.ParseLines(golden_lines, message)
|
||||
candidate = text_format.MessageToString(message)
|
||||
# The Python implementation emits "1.0" for the double value that the C++
|
||||
# implementation emits as "1".
|
||||
candidate = candidate.replace('1.0', '1', 2)
|
||||
self.assertMultiLineEqual(candidate, ''.join(golden_lines))
|
||||
# message = map_unittest_pb2.TestMap()
|
||||
# text_format.ParseLines(golden_lines, message)
|
||||
# candidate = text_format.MessageToString(message)
|
||||
# # The Python implementation emits "1.0" for the double value that the C++
|
||||
# # implementation emits as "1".
|
||||
# candidate = candidate.replace('1.0', '1', 2)
|
||||
# candidate = candidate.replace('0.0', '0', 2)
|
||||
# self.assertMultiLineEqual(candidate, ''.join(golden_lines))
|
||||
|
||||
|
||||
# Tests of proto2-only features (MessageSet, extensions, etc.).
|
||||
|
@ -45,6 +45,7 @@ TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
|
||||
|
||||
__author__ = 'robinson@google.com (Will Robinson)'
|
||||
|
||||
import numbers
|
||||
import six
|
||||
|
||||
if six.PY3:
|
||||
@ -126,11 +127,11 @@ class IntValueChecker(object):
|
||||
"""Checker used for integer fields. Performs type-check and range check."""
|
||||
|
||||
def CheckValue(self, proposed_value):
|
||||
if not isinstance(proposed_value, six.integer_types):
|
||||
if not isinstance(proposed_value, numbers.Integral):
|
||||
message = ('%.1024r has type %s, but expected one of: %s' %
|
||||
(proposed_value, type(proposed_value), six.integer_types))
|
||||
raise TypeError(message)
|
||||
if not self._MIN <= proposed_value <= self._MAX:
|
||||
if not self._MIN <= int(proposed_value) <= self._MAX:
|
||||
raise ValueError('Value out of range: %d' % proposed_value)
|
||||
# We force 32-bit values to int and 64-bit values to long to make
|
||||
# alternate implementations where the distinction is more significant
|
||||
@ -150,11 +151,11 @@ class EnumValueChecker(object):
|
||||
self._enum_type = enum_type
|
||||
|
||||
def CheckValue(self, proposed_value):
|
||||
if not isinstance(proposed_value, six.integer_types):
|
||||
if not isinstance(proposed_value, numbers.Integral):
|
||||
message = ('%.1024r has type %s, but expected one of: %s' %
|
||||
(proposed_value, type(proposed_value), six.integer_types))
|
||||
raise TypeError(message)
|
||||
if proposed_value not in self._enum_type.values_by_number:
|
||||
if int(proposed_value) not in self._enum_type.values_by_number:
|
||||
raise ValueError('Unknown enum value: %d' % proposed_value)
|
||||
return proposed_value
|
||||
|
||||
@ -223,11 +224,11 @@ _VALUE_CHECKERS = {
|
||||
_FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
|
||||
_FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
|
||||
_FieldDescriptor.CPPTYPE_DOUBLE: TypeCheckerWithDefault(
|
||||
0.0, float, int, long),
|
||||
0.0, numbers.Real),
|
||||
_FieldDescriptor.CPPTYPE_FLOAT: TypeCheckerWithDefault(
|
||||
0.0, float, int, long),
|
||||
0.0, numbers.Real),
|
||||
_FieldDescriptor.CPPTYPE_BOOL: TypeCheckerWithDefault(
|
||||
False, bool, int),
|
||||
False, bool, numbers.Integral),
|
||||
_FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes),
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,9 @@ Simple usage example:
|
||||
__author__ = 'jieluo@google.com (Jie Luo)'
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from ordereddict import OrderedDict #PY26
|
||||
from ordereddict import OrderedDict #PY26
|
||||
import base64
|
||||
import json
|
||||
import math
|
||||
|
@ -319,6 +319,51 @@ PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyFileDescriptor_FromDescriptor(file_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) {
|
||||
PyObject* message_descriptor;
|
||||
int number;
|
||||
if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) {
|
||||
return NULL;
|
||||
}
|
||||
const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(
|
||||
message_descriptor);
|
||||
if (descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const FieldDescriptor* extension_descriptor =
|
||||
self->pool->FindExtensionByNumber(descriptor, number);
|
||||
if (extension_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find extension %d", number);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyFieldDescriptor_FromDescriptor(extension_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindAllExtensions(PyDescriptorPool* self, PyObject* arg) {
|
||||
const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(arg);
|
||||
if (descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<const FieldDescriptor*> extensions;
|
||||
self->pool->FindAllExtensions(descriptor, &extensions);
|
||||
|
||||
ScopedPyObjectPtr result(PyList_New(extensions.size()));
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i < extensions.size(); i++) {
|
||||
PyObject* extension = PyFieldDescriptor_FromDescriptor(extensions[i]);
|
||||
if (extension == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyList_SET_ITEM(result.get(), i, extension); // Steals the reference.
|
||||
}
|
||||
return result.release();
|
||||
}
|
||||
|
||||
// These functions should not exist -- the only valid way to create
|
||||
// descriptors is to call Add() or AddSerializedFile().
|
||||
// But these AddDescriptor() functions were created in Python and some people
|
||||
@ -376,6 +421,22 @@ PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
const FieldDescriptor* extension_descriptor =
|
||||
PyFieldDescriptor_AsDescriptor(descriptor);
|
||||
if (!extension_descriptor) {
|
||||
return NULL;
|
||||
}
|
||||
if (extension_descriptor !=
|
||||
self->pool->FindExtensionByName(extension_descriptor->full_name())) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The extension descriptor %s does not belong to this pool",
|
||||
extension_descriptor->full_name().c_str());
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// The code below loads new Descriptors from a serialized FileDescriptorProto.
|
||||
|
||||
|
||||
@ -475,6 +536,8 @@ static PyMethodDef Methods[] = {
|
||||
"No-op. Add() must have been called before." },
|
||||
{ "AddEnumDescriptor", (PyCFunction)AddEnumDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
{ "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
|
||||
{ "FindFileByName", (PyCFunction)FindFileByName, METH_O,
|
||||
"Searches for a file descriptor by its .proto name." },
|
||||
@ -495,6 +558,10 @@ static PyMethodDef Methods[] = {
|
||||
|
||||
{ "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O,
|
||||
"Gets the FileDescriptor containing the specified symbol." },
|
||||
{ "FindExtensionByNumber", (PyCFunction)FindExtensionByNumber, METH_VARARGS,
|
||||
"Gets the extension descriptor for the given number." },
|
||||
{ "FindAllExtensions", (PyCFunction)FindAllExtensions, METH_O,
|
||||
"Gets all known extensions of the given message descriptor." },
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/dynamic_message.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/pyext/descriptor.h>
|
||||
#include <google/protobuf/pyext/message.h>
|
||||
#include <google/protobuf/pyext/message_factory.h>
|
||||
@ -46,6 +47,16 @@
|
||||
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#if PY_VERSION_HEX < 0x03030000
|
||||
#error "Python 3.0 - 3.2 are not supported."
|
||||
#endif
|
||||
#define PyString_AsStringAndSize(ob, charpp, sizep) \
|
||||
(PyUnicode_Check(ob)? \
|
||||
((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
|
||||
PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
|
||||
#endif
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace python {
|
||||
@ -90,6 +101,7 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
|
||||
|
||||
if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
|
||||
descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
// TODO(plabatut): consider building the class on the fly!
|
||||
PyObject* sub_message = cmessage::InternalGetSubMessage(
|
||||
self->parent, descriptor);
|
||||
if (sub_message == NULL) {
|
||||
@ -101,7 +113,17 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
|
||||
|
||||
if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
|
||||
if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
CMessageClass* message_class = message_factory::GetMessageClass(
|
||||
// On the fly message class creation is needed to support the following
|
||||
// situation:
|
||||
// 1- add FileDescriptor to the pool that contains extensions of a message
|
||||
// defined by another proto file. Do not create any message classes.
|
||||
// 2- instantiate an extended message, and access the extension using
|
||||
// the field descriptor.
|
||||
// 3- the extension submessage fails to be returned, because no class has
|
||||
// been created.
|
||||
// It happens when deserializing text proto format, or when enumerating
|
||||
// fields of a deserialized message.
|
||||
CMessageClass* message_class = message_factory::GetOrCreateMessageClass(
|
||||
cmessage::GetFactoryForMessage(self->parent),
|
||||
descriptor->message_type());
|
||||
if (message_class == NULL) {
|
||||
@ -154,34 +176,51 @@ int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
|
||||
ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
|
||||
reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
|
||||
if (extensions_by_name == NULL) {
|
||||
PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) {
|
||||
char* name;
|
||||
Py_ssize_t name_size;
|
||||
if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject* result = PyDict_GetItem(extensions_by_name.get(), name);
|
||||
if (result == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
} else {
|
||||
Py_INCREF(result);
|
||||
return result;
|
||||
|
||||
PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool;
|
||||
const FieldDescriptor* message_extension =
|
||||
pool->pool->FindExtensionByName(string(name, name_size));
|
||||
if (message_extension == NULL) {
|
||||
// Is is the name of a message set extension?
|
||||
const Descriptor* message_descriptor = pool->pool->FindMessageTypeByName(
|
||||
string(name, name_size));
|
||||
if (message_descriptor && message_descriptor->extension_count() > 0) {
|
||||
const FieldDescriptor* extension = message_descriptor->extension(0);
|
||||
if (extension->is_extension() &&
|
||||
extension->containing_type()->options().message_set_wire_format() &&
|
||||
extension->type() == FieldDescriptor::TYPE_MESSAGE &&
|
||||
extension->label() == FieldDescriptor::LABEL_OPTIONAL) {
|
||||
message_extension = extension;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message_extension == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
return PyFieldDescriptor_FromDescriptor(message_extension);
|
||||
}
|
||||
|
||||
PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number) {
|
||||
ScopedPyObjectPtr extensions_by_number(PyObject_GetAttrString(
|
||||
reinterpret_cast<PyObject*>(self->parent), "_extensions_by_number"));
|
||||
if (extensions_by_number == NULL) {
|
||||
PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) {
|
||||
int64 number = PyLong_AsLong(arg);
|
||||
if (number == -1 && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject* result = PyDict_GetItem(extensions_by_number.get(), number);
|
||||
if (result == NULL) {
|
||||
|
||||
PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool;
|
||||
const FieldDescriptor* message_extension = pool->pool->FindExtensionByNumber(
|
||||
self->parent->message->GetDescriptor(), number);
|
||||
if (message_extension == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
} else {
|
||||
Py_INCREF(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
return PyFieldDescriptor_FromDescriptor(message_extension);
|
||||
}
|
||||
|
||||
ExtensionDict* NewExtensionDict(CMessage *parent) {
|
||||
|
@ -374,7 +374,7 @@ static int InitializeAndCopyToParentContainer(MapContainer* from,
|
||||
// A somewhat roundabout way of copying just one field from old_message to
|
||||
// new_message. This is the best we can do with what Reflection gives us.
|
||||
Message* mutable_old = from->GetMutableMessage();
|
||||
vector<const FieldDescriptor*> fields;
|
||||
std::vector<const FieldDescriptor*> fields;
|
||||
fields.push_back(from->parent_field_descriptor);
|
||||
|
||||
// Move the map field into the new message.
|
||||
|
@ -64,11 +64,11 @@
|
||||
#include <google/protobuf/pyext/repeated_scalar_container.h>
|
||||
#include <google/protobuf/pyext/map_container.h>
|
||||
#include <google/protobuf/pyext/message_factory.h>
|
||||
#include <google/protobuf/pyext/safe_numerics.h>
|
||||
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define PyInt_Check PyLong_Check
|
||||
#define PyInt_AsLong PyLong_AsLong
|
||||
#define PyInt_FromLong PyLong_FromLong
|
||||
#define PyInt_FromSize_t PyLong_FromSize_t
|
||||
@ -92,8 +92,6 @@ namespace protobuf {
|
||||
namespace python {
|
||||
|
||||
static PyObject* kDESCRIPTOR;
|
||||
static PyObject* k_extensions_by_name;
|
||||
static PyObject* k_extensions_by_number;
|
||||
PyObject* EnumTypeWrapper_class;
|
||||
static PyObject* PythonMessage_class;
|
||||
static PyObject* kEmptyWeakref;
|
||||
@ -128,19 +126,6 @@ static bool AddFieldNumberToClass(
|
||||
|
||||
// Finalize the creation of the Message class.
|
||||
static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
|
||||
// If there are extension_ranges, the message is "extendable", and extension
|
||||
// classes will register themselves in this class.
|
||||
if (descriptor->extension_range_count() > 0) {
|
||||
ScopedPyObjectPtr by_name(PyDict_New());
|
||||
if (PyObject_SetAttr(cls, k_extensions_by_name, by_name.get()) < 0) {
|
||||
return -1;
|
||||
}
|
||||
ScopedPyObjectPtr by_number(PyDict_New());
|
||||
if (PyObject_SetAttr(cls, k_extensions_by_number, by_number.get()) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// For each field set: cls.<field>_FIELD_NUMBER = <number>
|
||||
for (int i = 0; i < descriptor->field_count(); ++i) {
|
||||
if (!AddFieldNumberToClass(cls, descriptor->field(i))) {
|
||||
@ -357,6 +342,61 @@ static int InsertEmptyWeakref(PyTypeObject *base_type) {
|
||||
#endif // PY_MAJOR_VERSION >= 3
|
||||
}
|
||||
|
||||
// The _extensions_by_name dictionary is built on every access.
|
||||
// TODO(amauryfa): Migrate all users to pool.FindAllExtensions()
|
||||
static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) {
|
||||
const PyDescriptorPool* pool = self->py_message_factory->pool;
|
||||
|
||||
std::vector<const FieldDescriptor*> extensions;
|
||||
pool->pool->FindAllExtensions(self->message_descriptor, &extensions);
|
||||
|
||||
ScopedPyObjectPtr result(PyDict_New());
|
||||
for (int i = 0; i < extensions.size(); i++) {
|
||||
ScopedPyObjectPtr extension(
|
||||
PyFieldDescriptor_FromDescriptor(extensions[i]));
|
||||
if (extension == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyDict_SetItemString(result.get(), extensions[i]->full_name().c_str(),
|
||||
extension.get()) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result.release();
|
||||
}
|
||||
|
||||
// The _extensions_by_number dictionary is built on every access.
|
||||
// TODO(amauryfa): Migrate all users to pool.FindExtensionByNumber()
|
||||
static PyObject* GetExtensionsByNumber(CMessageClass *self, void *closure) {
|
||||
const PyDescriptorPool* pool = self->py_message_factory->pool;
|
||||
|
||||
std::vector<const FieldDescriptor*> extensions;
|
||||
pool->pool->FindAllExtensions(self->message_descriptor, &extensions);
|
||||
|
||||
ScopedPyObjectPtr result(PyDict_New());
|
||||
for (int i = 0; i < extensions.size(); i++) {
|
||||
ScopedPyObjectPtr extension(
|
||||
PyFieldDescriptor_FromDescriptor(extensions[i]));
|
||||
if (extension == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr number(PyInt_FromLong(extensions[i]->number()));
|
||||
if (number == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyDict_SetItem(result.get(), number.get(), extension.get()) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result.release();
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
{"_extensions_by_name", (getter)GetExtensionsByName, NULL},
|
||||
{"_extensions_by_number", (getter)GetExtensionsByNumber, NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
} // namespace message_meta
|
||||
|
||||
PyTypeObject CMessageClass_Type = {
|
||||
@ -389,7 +429,7 @@ PyTypeObject CMessageClass_Type = {
|
||||
0, // tp_iternext
|
||||
0, // tp_methods
|
||||
0, // tp_members
|
||||
0, // tp_getset
|
||||
message_meta::Getters, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
@ -525,23 +565,10 @@ int ForEachCompositeField(CMessage* self, Visitor visitor) {
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Constants used for integer type range checking.
|
||||
PyObject* kPythonZero;
|
||||
PyObject* kint32min_py;
|
||||
PyObject* kint32max_py;
|
||||
PyObject* kuint32max_py;
|
||||
PyObject* kint64min_py;
|
||||
PyObject* kint64max_py;
|
||||
PyObject* kuint64max_py;
|
||||
|
||||
PyObject* EncodeError_class;
|
||||
PyObject* DecodeError_class;
|
||||
PyObject* PickleError_class;
|
||||
|
||||
// Constant PyString values used for GetAttr/GetItem.
|
||||
static PyObject* k_cdescriptor;
|
||||
static PyObject* kfull_name;
|
||||
|
||||
/* Is 64bit */
|
||||
void FormatTypeError(PyObject* arg, char* expected_types) {
|
||||
PyObject* repr = PyObject_Repr(arg);
|
||||
@ -555,68 +582,126 @@ void FormatTypeError(PyObject* arg, char* expected_types) {
|
||||
}
|
||||
}
|
||||
|
||||
void OutOfRangeError(PyObject* arg) {
|
||||
PyObject *s = PyObject_Str(arg);
|
||||
if (s) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Value out of range: %s",
|
||||
PyString_AsString(s));
|
||||
Py_DECREF(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<class RangeType, class ValueType>
|
||||
bool VerifyIntegerCastAndRange(PyObject* arg, ValueType value) {
|
||||
if GOOGLE_PREDICT_FALSE(value == -1 && PyErr_Occurred()) {
|
||||
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
|
||||
// Replace it with the same ValueError as pure python protos instead of
|
||||
// the default one.
|
||||
PyErr_Clear();
|
||||
OutOfRangeError(arg);
|
||||
} // Otherwise propagate existing error.
|
||||
return false;
|
||||
}
|
||||
if GOOGLE_PREDICT_FALSE(!IsValidNumericCast<RangeType>(value)) {
|
||||
OutOfRangeError(arg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool CheckAndGetInteger(
|
||||
PyObject* arg, T* value, PyObject* min, PyObject* max) {
|
||||
bool is_long = PyLong_Check(arg);
|
||||
bool CheckAndGetInteger(PyObject* arg, T* value) {
|
||||
// The fast path.
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
if (!PyInt_Check(arg) && !is_long) {
|
||||
// For the typical case, offer a fast path.
|
||||
if GOOGLE_PREDICT_TRUE(PyInt_Check(arg)) {
|
||||
long int_result = PyInt_AsLong(arg);
|
||||
if GOOGLE_PREDICT_TRUE(IsValidNumericCast<T>(int_result)) {
|
||||
*value = static_cast<T>(int_result);
|
||||
return true;
|
||||
} else {
|
||||
OutOfRangeError(arg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// This effectively defines an integer as "an object that can be cast as
|
||||
// an integer and can be used as an ordinal number".
|
||||
// This definition includes everything that implements numbers.Integral
|
||||
// and shouldn't cast the net too wide.
|
||||
if GOOGLE_PREDICT_FALSE(!PyIndex_Check(arg)) {
|
||||
FormatTypeError(arg, "int, long");
|
||||
return false;
|
||||
}
|
||||
if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
|
||||
#else
|
||||
if (!is_long) {
|
||||
FormatTypeError(arg, "int");
|
||||
return false;
|
||||
}
|
||||
if (PyObject_RichCompareBool(min, arg, Py_LE) != 1 ||
|
||||
PyObject_RichCompareBool(max, arg, Py_GE) != 1) {
|
||||
#endif
|
||||
if (!PyErr_Occurred()) {
|
||||
PyObject *s = PyObject_Str(arg);
|
||||
if (s) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Value out of range: %s",
|
||||
PyString_AsString(s));
|
||||
Py_DECREF(s);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
if (!is_long) {
|
||||
*value = static_cast<T>(PyInt_AsLong(arg));
|
||||
} else // NOLINT
|
||||
#endif
|
||||
{
|
||||
if (min == kPythonZero) {
|
||||
*value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
|
||||
|
||||
// Now we have an integral number so we can safely use PyLong_ functions.
|
||||
// We need to treat the signed and unsigned cases differently in case arg is
|
||||
// holding a value above the maximum for signed longs.
|
||||
if (std::numeric_limits<T>::min() == 0) {
|
||||
// Unsigned case.
|
||||
unsigned PY_LONG_LONG ulong_result;
|
||||
if (PyLong_Check(arg)) {
|
||||
ulong_result = PyLong_AsUnsignedLongLong(arg);
|
||||
} else {
|
||||
*value = static_cast<T>(PyLong_AsLongLong(arg));
|
||||
// Unlike PyLong_AsLongLong, PyLong_AsUnsignedLongLong is very
|
||||
// picky about the exact type.
|
||||
PyObject* casted = PyNumber_Long(arg);
|
||||
if GOOGLE_PREDICT_FALSE(casted == NULL) {
|
||||
// Propagate existing error.
|
||||
return false;
|
||||
}
|
||||
ulong_result = PyLong_AsUnsignedLongLong(casted);
|
||||
Py_DECREF(casted);
|
||||
}
|
||||
if (VerifyIntegerCastAndRange<T, unsigned PY_LONG_LONG>(arg,
|
||||
ulong_result)) {
|
||||
*value = static_cast<T>(ulong_result);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Signed case.
|
||||
PY_LONG_LONG long_result;
|
||||
PyNumberMethods *nb;
|
||||
if ((nb = arg->ob_type->tp_as_number) != NULL && nb->nb_int != NULL) {
|
||||
// PyLong_AsLongLong requires it to be a long or to have an __int__()
|
||||
// method.
|
||||
long_result = PyLong_AsLongLong(arg);
|
||||
} else {
|
||||
// Valid subclasses of numbers.Integral should have a __long__() method
|
||||
// so fall back to that.
|
||||
PyObject* casted = PyNumber_Long(arg);
|
||||
if GOOGLE_PREDICT_FALSE(casted == NULL) {
|
||||
// Propagate existing error.
|
||||
return false;
|
||||
}
|
||||
long_result = PyLong_AsLongLong(casted);
|
||||
Py_DECREF(casted);
|
||||
}
|
||||
if (VerifyIntegerCastAndRange<T, PY_LONG_LONG>(arg, long_result)) {
|
||||
*value = static_cast<T>(long_result);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// These are referenced by repeated_scalar_container, and must
|
||||
// be explicitly instantiated.
|
||||
template bool CheckAndGetInteger<int32>(
|
||||
PyObject*, int32*, PyObject*, PyObject*);
|
||||
template bool CheckAndGetInteger<int64>(
|
||||
PyObject*, int64*, PyObject*, PyObject*);
|
||||
template bool CheckAndGetInteger<uint32>(
|
||||
PyObject*, uint32*, PyObject*, PyObject*);
|
||||
template bool CheckAndGetInteger<uint64>(
|
||||
PyObject*, uint64*, PyObject*, PyObject*);
|
||||
template bool CheckAndGetInteger<int32>(PyObject*, int32*);
|
||||
template bool CheckAndGetInteger<int64>(PyObject*, int64*);
|
||||
template bool CheckAndGetInteger<uint32>(PyObject*, uint32*);
|
||||
template bool CheckAndGetInteger<uint64>(PyObject*, uint64*);
|
||||
|
||||
bool CheckAndGetDouble(PyObject* arg, double* value) {
|
||||
if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
|
||||
!PyFloat_Check(arg)) {
|
||||
*value = PyFloat_AsDouble(arg);
|
||||
if GOOGLE_PREDICT_FALSE(*value == -1 && PyErr_Occurred()) {
|
||||
FormatTypeError(arg, "int, long, float");
|
||||
return false;
|
||||
}
|
||||
*value = PyFloat_AsDouble(arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -630,11 +715,13 @@ bool CheckAndGetFloat(PyObject* arg, float* value) {
|
||||
}
|
||||
|
||||
bool CheckAndGetBool(PyObject* arg, bool* value) {
|
||||
if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
|
||||
long long_value = PyInt_AsLong(arg);
|
||||
if (long_value == -1 && PyErr_Occurred()) {
|
||||
FormatTypeError(arg, "int, long, bool");
|
||||
return false;
|
||||
}
|
||||
*value = static_cast<bool>(PyInt_AsLong(arg));
|
||||
*value = static_cast<bool>(long_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -966,20 +1053,7 @@ int InternalDeleteRepeatedField(
|
||||
int min, max;
|
||||
length = reflection->FieldSize(*message, field_descriptor);
|
||||
|
||||
if (PyInt_Check(slice) || PyLong_Check(slice)) {
|
||||
from = to = PyLong_AsLong(slice);
|
||||
if (from < 0) {
|
||||
from = to = length + from;
|
||||
}
|
||||
step = 1;
|
||||
min = max = from;
|
||||
|
||||
// Range check.
|
||||
if (from < 0 || from >= length) {
|
||||
PyErr_Format(PyExc_IndexError, "list assignment index out of range");
|
||||
return -1;
|
||||
}
|
||||
} else if (PySlice_Check(slice)) {
|
||||
if (PySlice_Check(slice)) {
|
||||
from = to = step = slice_length = 0;
|
||||
PySlice_GetIndicesEx(
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
@ -996,8 +1070,23 @@ int InternalDeleteRepeatedField(
|
||||
max = from;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "list indices must be integers");
|
||||
return -1;
|
||||
from = to = PyLong_AsLong(slice);
|
||||
if (from == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "list indices must be integers");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (from < 0) {
|
||||
from = to = length + from;
|
||||
}
|
||||
step = 1;
|
||||
min = max = from;
|
||||
|
||||
// Range check.
|
||||
if (from < 0 || from >= length) {
|
||||
PyErr_Format(PyExc_IndexError, "list assignment index out of range");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Py_ssize_t i = from;
|
||||
@ -1958,99 +2047,29 @@ static PyObject* ByteSize(CMessage* self, PyObject* args) {
|
||||
return PyLong_FromLong(self->message->ByteSize());
|
||||
}
|
||||
|
||||
static PyObject* RegisterExtension(PyObject* cls,
|
||||
PyObject* extension_handle) {
|
||||
PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle) {
|
||||
const FieldDescriptor* descriptor =
|
||||
GetExtensionDescriptor(extension_handle);
|
||||
if (descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ScopedPyObjectPtr extensions_by_name(
|
||||
PyObject_GetAttr(cls, k_extensions_by_name));
|
||||
if (extensions_by_name == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "no extensions_by_name on class");
|
||||
if (!PyObject_TypeCheck(cls, &CMessageClass_Type)) {
|
||||
PyErr_Format(PyExc_TypeError, "Expected a message class, got %s",
|
||||
cls->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr full_name(PyObject_GetAttr(extension_handle, kfull_name));
|
||||
if (full_name == NULL) {
|
||||
CMessageClass *message_class = reinterpret_cast<CMessageClass*>(cls);
|
||||
if (message_class == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If the extension was already registered, check that it is the same.
|
||||
PyObject* existing_extension =
|
||||
PyDict_GetItem(extensions_by_name.get(), full_name.get());
|
||||
if (existing_extension != NULL) {
|
||||
const FieldDescriptor* existing_extension_descriptor =
|
||||
GetExtensionDescriptor(existing_extension);
|
||||
if (existing_extension_descriptor != descriptor) {
|
||||
PyErr_SetString(PyExc_ValueError, "Double registration of Extensions");
|
||||
return NULL;
|
||||
}
|
||||
// Nothing else to do.
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (PyDict_SetItem(extensions_by_name.get(), full_name.get(),
|
||||
extension_handle) < 0) {
|
||||
const FieldDescriptor* existing_extension =
|
||||
message_class->py_message_factory->pool->pool->FindExtensionByNumber(
|
||||
descriptor->containing_type(), descriptor->number());
|
||||
if (existing_extension != NULL && existing_extension != descriptor) {
|
||||
PyErr_SetString(PyExc_ValueError, "Double registration of Extensions");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Also store a mapping from extension number to implementing class.
|
||||
ScopedPyObjectPtr extensions_by_number(
|
||||
PyObject_GetAttr(cls, k_extensions_by_number));
|
||||
if (extensions_by_number == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "no extensions_by_number on class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ScopedPyObjectPtr number(PyObject_GetAttrString(extension_handle, "number"));
|
||||
if (number == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If the extension was already registered by number, check that it is the
|
||||
// same.
|
||||
existing_extension = PyDict_GetItem(extensions_by_number.get(), number.get());
|
||||
if (existing_extension != NULL) {
|
||||
const FieldDescriptor* existing_extension_descriptor =
|
||||
GetExtensionDescriptor(existing_extension);
|
||||
if (existing_extension_descriptor != descriptor) {
|
||||
const Descriptor* msg_desc = GetMessageDescriptor(
|
||||
reinterpret_cast<PyTypeObject*>(cls));
|
||||
PyErr_Format(
|
||||
PyExc_ValueError,
|
||||
"Extensions \"%s\" and \"%s\" both try to extend message type "
|
||||
"\"%s\" with field number %ld.",
|
||||
existing_extension_descriptor->full_name().c_str(),
|
||||
descriptor->full_name().c_str(),
|
||||
msg_desc->full_name().c_str(),
|
||||
PyInt_AsLong(number.get()));
|
||||
return NULL;
|
||||
}
|
||||
// Nothing else to do.
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if (PyDict_SetItem(extensions_by_number.get(), number.get(),
|
||||
extension_handle) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if it's a message set
|
||||
if (descriptor->is_extension() &&
|
||||
descriptor->containing_type()->options().message_set_wire_format() &&
|
||||
descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
|
||||
descriptor->label() == FieldDescriptor::LABEL_OPTIONAL) {
|
||||
ScopedPyObjectPtr message_name(PyString_FromStringAndSize(
|
||||
descriptor->message_type()->full_name().c_str(),
|
||||
descriptor->message_type()->full_name().size()));
|
||||
if (message_name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyDict_SetItem(extensions_by_name.get(), message_name.get(),
|
||||
extension_handle);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@ -2087,7 +2106,7 @@ static PyObject* WhichOneof(CMessage* self, PyObject* arg) {
|
||||
static PyObject* GetExtensionDict(CMessage* self, void *closure);
|
||||
|
||||
static PyObject* ListFields(CMessage* self) {
|
||||
vector<const FieldDescriptor*> fields;
|
||||
std::vector<const FieldDescriptor*> fields;
|
||||
self->message->GetReflection()->ListFields(*self->message, &fields);
|
||||
|
||||
// Normally, the list will be exactly the size of the fields.
|
||||
@ -2178,7 +2197,7 @@ static PyObject* DiscardUnknownFields(CMessage* self) {
|
||||
|
||||
PyObject* FindInitializationErrors(CMessage* self) {
|
||||
Message* message = self->message;
|
||||
vector<string> errors;
|
||||
std::vector<string> errors;
|
||||
message->FindInitializationErrors(&errors);
|
||||
|
||||
PyObject* error_list = PyList_New(errors.size());
|
||||
@ -2570,11 +2589,24 @@ static PyObject* GetExtensionDict(CMessage* self, void *closure) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject* GetExtensionsByName(CMessage *self, void *closure) {
|
||||
return message_meta::GetExtensionsByName(
|
||||
reinterpret_cast<CMessageClass*>(Py_TYPE(self)), closure);
|
||||
}
|
||||
|
||||
static PyObject* GetExtensionsByNumber(CMessage *self, void *closure) {
|
||||
return message_meta::GetExtensionsByNumber(
|
||||
reinterpret_cast<CMessageClass*>(Py_TYPE(self)), closure);
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
{"Extensions", (getter)GetExtensionDict, NULL, "Extension dict"},
|
||||
{"_extensions_by_name", (getter)GetExtensionsByName, NULL},
|
||||
{"_extensions_by_number", (getter)GetExtensionsByNumber, NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
||||
static PyMethodDef Methods[] = {
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
@ -2835,19 +2867,7 @@ void InitGlobals() {
|
||||
// TODO(gps): Check all return values in this function for NULL and propagate
|
||||
// the error (MemoryError) on up to result in an import failure. These should
|
||||
// also be freed and reset to NULL during finalization.
|
||||
kPythonZero = PyInt_FromLong(0);
|
||||
kint32min_py = PyInt_FromLong(kint32min);
|
||||
kint32max_py = PyInt_FromLong(kint32max);
|
||||
kuint32max_py = PyLong_FromLongLong(kuint32max);
|
||||
kint64min_py = PyLong_FromLongLong(kint64min);
|
||||
kint64max_py = PyLong_FromLongLong(kint64max);
|
||||
kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
|
||||
|
||||
kDESCRIPTOR = PyString_FromString("DESCRIPTOR");
|
||||
k_cdescriptor = PyString_FromString("_cdescriptor");
|
||||
kfull_name = PyString_FromString("full_name");
|
||||
k_extensions_by_name = PyString_FromString("_extensions_by_name");
|
||||
k_extensions_by_number = PyString_FromString("_extensions_by_number");
|
||||
|
||||
PyObject *dummy_obj = PySet_New(NULL);
|
||||
kEmptyWeakref = PyWeakref_NewRef(dummy_obj, NULL);
|
||||
@ -2887,25 +2907,6 @@ bool InitProto2MessageModule(PyObject *m) {
|
||||
// DESCRIPTOR is set on each protocol buffer message class elsewhere, but set
|
||||
// it here as well to document that subclasses need to set it.
|
||||
PyDict_SetItem(CMessage_Type.tp_dict, kDESCRIPTOR, Py_None);
|
||||
// Subclasses with message extensions will override _extensions_by_name and
|
||||
// _extensions_by_number with fresh mutable dictionaries in AddDescriptors.
|
||||
// All other classes can share this same immutable mapping.
|
||||
ScopedPyObjectPtr empty_dict(PyDict_New());
|
||||
if (empty_dict == NULL) {
|
||||
return false;
|
||||
}
|
||||
ScopedPyObjectPtr immutable_dict(PyDictProxy_New(empty_dict.get()));
|
||||
if (immutable_dict == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (PyDict_SetItem(CMessage_Type.tp_dict,
|
||||
k_extensions_by_name, immutable_dict.get()) < 0) {
|
||||
return false;
|
||||
}
|
||||
if (PyDict_SetItem(CMessage_Type.tp_dict,
|
||||
k_extensions_by_number, immutable_dict.get()) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(&CMessage_Type));
|
||||
|
||||
|
@ -117,6 +117,7 @@ typedef struct CMessage {
|
||||
PyObject* weakreflist;
|
||||
} CMessage;
|
||||
|
||||
extern PyTypeObject CMessageClass_Type;
|
||||
extern PyTypeObject CMessage_Type;
|
||||
|
||||
|
||||
@ -235,6 +236,10 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs);
|
||||
|
||||
PyObject* MergeFrom(CMessage* self, PyObject* arg);
|
||||
|
||||
// This method does not do anything beyond checking that no other extension
|
||||
// has been registered with the same field number on this class.
|
||||
PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle);
|
||||
|
||||
// Retrieves an attribute named 'name' from CMessage 'self'. Returns
|
||||
// the attribute value on success, or NULL on failure.
|
||||
//
|
||||
@ -275,25 +280,25 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
|
||||
|
||||
#define GOOGLE_CHECK_GET_INT32(arg, value, err) \
|
||||
int32 value; \
|
||||
if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
|
||||
if (!CheckAndGetInteger(arg, &value)) { \
|
||||
return err; \
|
||||
}
|
||||
|
||||
#define GOOGLE_CHECK_GET_INT64(arg, value, err) \
|
||||
int64 value; \
|
||||
if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
|
||||
if (!CheckAndGetInteger(arg, &value)) { \
|
||||
return err; \
|
||||
}
|
||||
|
||||
#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
|
||||
uint32 value; \
|
||||
if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
|
||||
if (!CheckAndGetInteger(arg, &value)) { \
|
||||
return err; \
|
||||
}
|
||||
|
||||
#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
|
||||
uint64 value; \
|
||||
if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
|
||||
if (!CheckAndGetInteger(arg, &value)) { \
|
||||
return err; \
|
||||
}
|
||||
|
||||
@ -316,20 +321,11 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
|
||||
}
|
||||
|
||||
|
||||
extern PyObject* kPythonZero;
|
||||
extern PyObject* kint32min_py;
|
||||
extern PyObject* kint32max_py;
|
||||
extern PyObject* kuint32max_py;
|
||||
extern PyObject* kint64min_py;
|
||||
extern PyObject* kint64max_py;
|
||||
extern PyObject* kuint64max_py;
|
||||
|
||||
#define FULL_MODULE_NAME "google.protobuf.pyext._message"
|
||||
|
||||
void FormatTypeError(PyObject* arg, char* expected_types);
|
||||
template<class T>
|
||||
bool CheckAndGetInteger(
|
||||
PyObject* arg, T* value, PyObject* min, PyObject* max);
|
||||
bool CheckAndGetInteger(PyObject* arg, T* value);
|
||||
bool CheckAndGetDouble(PyObject* arg, double* value);
|
||||
bool CheckAndGetFloat(PyObject* arg, float* value);
|
||||
bool CheckAndGetBool(PyObject* arg, bool* value);
|
||||
|
@ -130,6 +130,72 @@ int RegisterMessageClass(PyMessageFactory* self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self,
|
||||
const Descriptor* descriptor) {
|
||||
// This is the same implementation as MessageFactory.GetPrototype().
|
||||
ScopedPyObjectPtr py_descriptor(
|
||||
PyMessageDescriptor_FromDescriptor(descriptor));
|
||||
if (py_descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// Do not create a MessageClass that already exists.
|
||||
hash_map<const Descriptor*, CMessageClass*>::iterator it =
|
||||
self->classes_by_descriptor->find(descriptor);
|
||||
if (it != self->classes_by_descriptor->end()) {
|
||||
Py_INCREF(it->second);
|
||||
return it->second;
|
||||
}
|
||||
// Create a new message class.
|
||||
ScopedPyObjectPtr args(Py_BuildValue(
|
||||
"s(){sOsOsO}", descriptor->name().c_str(),
|
||||
"DESCRIPTOR", py_descriptor.get(),
|
||||
"__module__", Py_None,
|
||||
"message_factory", self));
|
||||
if (args == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr message_class(PyObject_CallObject(
|
||||
reinterpret_cast<PyObject*>(&CMessageClass_Type), args.get()));
|
||||
if (message_class == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// Create messages class for the messages used by the fields, and registers
|
||||
// all extensions for these messages during the recursion.
|
||||
for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) {
|
||||
const Descriptor* sub_descriptor =
|
||||
descriptor->field(field_idx)->message_type();
|
||||
// It is NULL if the field type is not a message.
|
||||
if (sub_descriptor != NULL) {
|
||||
CMessageClass* result = GetOrCreateMessageClass(self, sub_descriptor);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
}
|
||||
|
||||
// Register extensions defined in this message.
|
||||
for (int ext_idx = 0 ; ext_idx < descriptor->extension_count() ; ext_idx++) {
|
||||
const FieldDescriptor* extension = descriptor->extension(ext_idx);
|
||||
ScopedPyObjectPtr py_extended_class(
|
||||
GetOrCreateMessageClass(self, extension->containing_type())
|
||||
->AsPyObject());
|
||||
if (py_extended_class == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr py_extension(PyFieldDescriptor_FromDescriptor(extension));
|
||||
if (py_extension == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr result(cmessage::RegisterExtension(
|
||||
py_extended_class.get(), py_extension.get()));
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return reinterpret_cast<CMessageClass*>(message_class.release());
|
||||
}
|
||||
|
||||
// Retrieve the message class added to our database.
|
||||
CMessageClass* GetMessageClass(PyMessageFactory* self,
|
||||
const Descriptor* message_descriptor) {
|
||||
|
@ -82,14 +82,14 @@ PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool);
|
||||
int RegisterMessageClass(PyMessageFactory* self,
|
||||
const Descriptor* message_descriptor,
|
||||
CMessageClass* message_class);
|
||||
|
||||
// Retrieves the Python class registered with the given message descriptor.
|
||||
//
|
||||
// Returns a *borrowed* reference if found, otherwise returns NULL with an
|
||||
// exception set.
|
||||
// Retrieves the Python class registered with the given message descriptor, or
|
||||
// fail with a TypeError. Returns a *borrowed* reference.
|
||||
CMessageClass* GetMessageClass(PyMessageFactory* self,
|
||||
const Descriptor* message_descriptor);
|
||||
|
||||
// Retrieves the Python class registered with the given message descriptor.
|
||||
// The class is created if not done yet. Returns a *new* reference.
|
||||
CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self,
|
||||
const Descriptor* message_descriptor);
|
||||
} // namespace message_factory
|
||||
|
||||
// Initialize objects used by this module.
|
||||
|
164
python/google/protobuf/pyext/safe_numerics.h
Normal file
164
python/google/protobuf/pyext/safe_numerics.h
Normal file
@ -0,0 +1,164 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__
|
||||
#define GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__
|
||||
// Copied from chromium with only changes to the namespace.
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace python {
|
||||
|
||||
template <bool SameSize, bool DestLarger,
|
||||
bool DestIsSigned, bool SourceIsSigned>
|
||||
struct IsValidNumericCastImpl;
|
||||
|
||||
#define BASE_NUMERIC_CAST_CASE_SPECIALIZATION(A, B, C, D, Code) \
|
||||
template <> struct IsValidNumericCastImpl<A, B, C, D> { \
|
||||
template <class Source, class DestBounds> static inline bool Test( \
|
||||
Source source, DestBounds min, DestBounds max) { \
|
||||
return Code; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define BASE_NUMERIC_CAST_CASE_SAME_SIZE(DestSigned, SourceSigned, Code) \
|
||||
BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
|
||||
true, true, DestSigned, SourceSigned, Code); \
|
||||
BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
|
||||
true, false, DestSigned, SourceSigned, Code)
|
||||
|
||||
#define BASE_NUMERIC_CAST_CASE_SOURCE_LARGER(DestSigned, SourceSigned, Code) \
|
||||
BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
|
||||
false, false, DestSigned, SourceSigned, Code); \
|
||||
|
||||
#define BASE_NUMERIC_CAST_CASE_DEST_LARGER(DestSigned, SourceSigned, Code) \
|
||||
BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
|
||||
false, true, DestSigned, SourceSigned, Code); \
|
||||
|
||||
// The three top level cases are:
|
||||
// - Same size
|
||||
// - Source larger
|
||||
// - Dest larger
|
||||
// And for each of those three cases, we handle the 4 different possibilities
|
||||
// of signed and unsigned. This gives 12 cases to handle, which we enumerate
|
||||
// below.
|
||||
//
|
||||
// The last argument in each of the macros is the actual comparison code. It
|
||||
// has three arguments available, source (the value), and min/max which are
|
||||
// the ranges of the destination.
|
||||
|
||||
|
||||
// These are the cases where both types have the same size.
|
||||
|
||||
// Both signed.
|
||||
BASE_NUMERIC_CAST_CASE_SAME_SIZE(true, true, true);
|
||||
// Both unsigned.
|
||||
BASE_NUMERIC_CAST_CASE_SAME_SIZE(false, false, true);
|
||||
// Dest unsigned, Source signed.
|
||||
BASE_NUMERIC_CAST_CASE_SAME_SIZE(false, true, source >= 0);
|
||||
// Dest signed, Source unsigned.
|
||||
// This cast is OK because Dest's max must be less than Source's.
|
||||
BASE_NUMERIC_CAST_CASE_SAME_SIZE(true, false,
|
||||
source <= static_cast<Source>(max));
|
||||
|
||||
|
||||
// These are the cases where Source is larger.
|
||||
|
||||
// Both unsigned.
|
||||
BASE_NUMERIC_CAST_CASE_SOURCE_LARGER(false, false, source <= max);
|
||||
// Both signed.
|
||||
BASE_NUMERIC_CAST_CASE_SOURCE_LARGER(true, true,
|
||||
source >= min && source <= max);
|
||||
// Dest is unsigned, Source is signed.
|
||||
BASE_NUMERIC_CAST_CASE_SOURCE_LARGER(false, true,
|
||||
source >= 0 && source <= max);
|
||||
// Dest is signed, Source is unsigned.
|
||||
// This cast is OK because Dest's max must be less than Source's.
|
||||
BASE_NUMERIC_CAST_CASE_SOURCE_LARGER(true, false,
|
||||
source <= static_cast<Source>(max));
|
||||
|
||||
|
||||
// These are the cases where Dest is larger.
|
||||
|
||||
// Both unsigned.
|
||||
BASE_NUMERIC_CAST_CASE_DEST_LARGER(false, false, true);
|
||||
// Both signed.
|
||||
BASE_NUMERIC_CAST_CASE_DEST_LARGER(true, true, true);
|
||||
// Dest is unsigned, Source is signed.
|
||||
BASE_NUMERIC_CAST_CASE_DEST_LARGER(false, true, source >= 0);
|
||||
// Dest is signed, Source is unsigned.
|
||||
BASE_NUMERIC_CAST_CASE_DEST_LARGER(true, false, true);
|
||||
|
||||
#undef BASE_NUMERIC_CAST_CASE_SPECIALIZATION
|
||||
#undef BASE_NUMERIC_CAST_CASE_SAME_SIZE
|
||||
#undef BASE_NUMERIC_CAST_CASE_SOURCE_LARGER
|
||||
#undef BASE_NUMERIC_CAST_CASE_DEST_LARGER
|
||||
|
||||
|
||||
// The main test for whether the conversion will under or overflow.
|
||||
template <class Dest, class Source>
|
||||
inline bool IsValidNumericCast(Source source) {
|
||||
typedef std::numeric_limits<Source> SourceLimits;
|
||||
typedef std::numeric_limits<Dest> DestLimits;
|
||||
GOOGLE_COMPILE_ASSERT(SourceLimits::is_specialized, argument_must_be_numeric);
|
||||
GOOGLE_COMPILE_ASSERT(SourceLimits::is_integer, argument_must_be_integral);
|
||||
GOOGLE_COMPILE_ASSERT(DestLimits::is_specialized, result_must_be_numeric);
|
||||
GOOGLE_COMPILE_ASSERT(DestLimits::is_integer, result_must_be_integral);
|
||||
|
||||
return IsValidNumericCastImpl<
|
||||
sizeof(Dest) == sizeof(Source),
|
||||
(sizeof(Dest) > sizeof(Source)),
|
||||
DestLimits::is_signed,
|
||||
SourceLimits::is_signed>::Test(
|
||||
source,
|
||||
DestLimits::min(),
|
||||
DestLimits::max());
|
||||
}
|
||||
|
||||
// checked_numeric_cast<> is analogous to static_cast<> for numeric types,
|
||||
// except that it CHECKs that the specified numeric conversion will not
|
||||
// overflow or underflow. Floating point arguments are not currently allowed
|
||||
// (this is COMPILE_ASSERTd), though this could be supported if necessary.
|
||||
template <class Dest, class Source>
|
||||
inline Dest checked_numeric_cast(Source source) {
|
||||
GOOGLE_CHECK(IsValidNumericCast<Dest>(source));
|
||||
return static_cast<Dest>(source);
|
||||
}
|
||||
|
||||
} // namespace python
|
||||
} // namespace protobuf
|
||||
|
||||
} // namespace google
|
||||
#endif // GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__
|
@ -161,6 +161,7 @@ nobase_include_HEADERS = \
|
||||
google/protobuf/compiler/java/java_names.h \
|
||||
google/protobuf/compiler/javanano/javanano_generator.h \
|
||||
google/protobuf/compiler/js/js_generator.h \
|
||||
google/protobuf/compiler/js/well_known_types_embed.h \
|
||||
google/protobuf/compiler/objectivec/objectivec_generator.h \
|
||||
google/protobuf/compiler/objectivec/objectivec_helpers.h \
|
||||
google/protobuf/compiler/php/php_generator.h \
|
||||
@ -399,6 +400,7 @@ libprotoc_la_SOURCES = \
|
||||
google/protobuf/compiler/java/java_doc_comment.cc \
|
||||
google/protobuf/compiler/java/java_doc_comment.h \
|
||||
google/protobuf/compiler/js/js_generator.cc \
|
||||
google/protobuf/compiler/js/well_known_types_embed.cc \
|
||||
google/protobuf/compiler/javanano/javanano_enum.cc \
|
||||
google/protobuf/compiler/javanano/javanano_enum.h \
|
||||
google/protobuf/compiler/javanano/javanano_enum_field.cc \
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
#include <google/protobuf/any.h>
|
||||
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace internal {
|
||||
@ -70,13 +72,11 @@ bool AnyMetadata::UnpackTo(Message* message) const {
|
||||
if (!InternalIs(message->GetDescriptor())) {
|
||||
return false;
|
||||
}
|
||||
return message->ParseFromString(
|
||||
value_->GetNoArena(&::google::protobuf::internal::GetEmptyString()));
|
||||
return message->ParseFromString(value_->GetNoArena());
|
||||
}
|
||||
|
||||
bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
|
||||
const string type_url = type_url_->GetNoArena(
|
||||
&::google::protobuf::internal::GetEmptyString());
|
||||
const string type_url = type_url_->GetNoArena();
|
||||
string full_name;
|
||||
if (!ParseAnyTypeUrl(type_url, &full_name)) {
|
||||
return false;
|
||||
|
@ -19,86 +19,88 @@
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class AnyDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Any> {};
|
||||
AnyDefaultTypeInternal _Any_default_instance_;
|
||||
|
||||
namespace {
|
||||
|
||||
const ::google::protobuf::Descriptor* Any_descriptor_ = NULL;
|
||||
const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
Any_reflection_ = NULL;
|
||||
::google::protobuf::Metadata file_level_metadata[1];
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
|
||||
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() {
|
||||
protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
|
||||
const ::google::protobuf::FileDescriptor* file =
|
||||
::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
|
||||
"google/protobuf/any.proto");
|
||||
GOOGLE_CHECK(file != NULL);
|
||||
Any_descriptor_ = file->message_type(0);
|
||||
static const int Any_offsets_[2] = {
|
||||
const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
|
||||
const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fany_2eproto() {
|
||||
static const ::google::protobuf::uint32 offsets[] = {
|
||||
~0u, // no _has_bits_
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_),
|
||||
~0u, // no _extensions_
|
||||
~0u, // no _oneof_case_
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, type_url_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_),
|
||||
};
|
||||
Any_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
Any_descriptor_,
|
||||
Any::internal_default_instance(),
|
||||
Any_offsets_,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
sizeof(Any),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_));
|
||||
return offsets;
|
||||
}
|
||||
|
||||
static const ::google::protobuf::internal::MigrationSchema schemas[] = {
|
||||
{ 0, -1, sizeof(Any)},
|
||||
};
|
||||
|
||||
static const ::google::protobuf::internal::DefaultInstanceData file_default_instances[] = {
|
||||
{reinterpret_cast<const ::google::protobuf::Message*>(&_Any_default_instance_), NULL},
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
|
||||
void protobuf_AssignDescriptors() {
|
||||
protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
|
||||
::google::protobuf::MessageFactory* factory = NULL;
|
||||
AssignDescriptors(
|
||||
"google/protobuf/any.proto", schemas, file_default_instances, protobuf_Offsets_google_2fprotobuf_2fany_2eproto(), factory,
|
||||
file_level_metadata, NULL, NULL);
|
||||
}
|
||||
|
||||
void protobuf_AssignDescriptorsOnce() {
|
||||
::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
|
||||
&protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto);
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
|
||||
}
|
||||
|
||||
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
|
||||
void protobuf_RegisterTypes(const ::std::string&) {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
|
||||
Any_descriptor_, Any::internal_default_instance());
|
||||
::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto() {
|
||||
Any_default_instance_.Shutdown();
|
||||
delete Any_reflection_;
|
||||
_Any_default_instance_.Shutdown();
|
||||
delete file_level_metadata[0].reflection;
|
||||
}
|
||||
|
||||
void protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_impl() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
::google::protobuf::internal::GetEmptyString();
|
||||
Any_default_instance_.DefaultConstruct();
|
||||
Any_default_instance_.get_mutable()->InitAsDefaultInstance();
|
||||
::google::protobuf::internal::InitProtobufDefaults();
|
||||
_Any_default_instance_.DefaultConstruct();
|
||||
}
|
||||
|
||||
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_once_);
|
||||
void protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto() {
|
||||
::google::protobuf::GoogleOnceInit(&protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_once_,
|
||||
&protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_impl);
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_impl);
|
||||
}
|
||||
void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto_impl() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto();
|
||||
static const char descriptor[] = {
|
||||
"\n\031google/protobuf/any.proto\022\017google.prot"
|
||||
"obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
|
||||
" \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
|
||||
"%github.com/golang/protobuf/ptypes/any\242\002"
|
||||
"\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
|
||||
"roto3"
|
||||
};
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n\031google/protobuf/any.proto\022\017google.prot"
|
||||
"obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
|
||||
" \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
|
||||
"%github.com/golang/protobuf/ptypes/any\242\002"
|
||||
"\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
|
||||
"roto3", 205);
|
||||
descriptor, 205);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/any.proto", &protobuf_RegisterTypes);
|
||||
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto);
|
||||
@ -116,16 +118,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fany_2eproto {
|
||||
}
|
||||
} static_descriptor_initializer_google_2fprotobuf_2fany_2eproto_;
|
||||
|
||||
namespace {
|
||||
|
||||
static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD GOOGLE_ATTRIBUTE_NORETURN;
|
||||
static void MergeFromFail(int line) {
|
||||
::google::protobuf::internal::MergeFromFail(__FILE__, line);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// ===================================================================
|
||||
|
||||
void Any::PackFrom(const ::google::protobuf::Message& message) {
|
||||
@ -148,20 +140,26 @@ const int Any::kValueFieldNumber;
|
||||
|
||||
Any::Any()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL), _any_metadata_(&type_url_, &value_) {
|
||||
if (this != internal_default_instance()) protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto();
|
||||
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
|
||||
protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto();
|
||||
}
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:google.protobuf.Any)
|
||||
}
|
||||
|
||||
void Any::InitAsDefaultInstance() {
|
||||
}
|
||||
|
||||
Any::Any(const Any& from)
|
||||
: ::google::protobuf::Message(),
|
||||
_internal_metadata_(NULL),
|
||||
_any_metadata_(&type_url_, &value_) {
|
||||
SharedCtor();
|
||||
UnsafeMergeFrom(from);
|
||||
_internal_metadata_(NULL),
|
||||
_cached_size_(0),
|
||||
_any_metadata_(&type_url_, &value_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.type_url().size() > 0) {
|
||||
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
|
||||
}
|
||||
value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.value().size() > 0) {
|
||||
value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_);
|
||||
}
|
||||
// @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
|
||||
}
|
||||
|
||||
@ -188,7 +186,7 @@ void Any::SetCachedSize(int size) const {
|
||||
}
|
||||
const ::google::protobuf::Descriptor* Any::descriptor() {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
return Any_descriptor_;
|
||||
return file_level_metadata[0].descriptor;
|
||||
}
|
||||
|
||||
const Any& Any::default_instance() {
|
||||
@ -196,8 +194,6 @@ const Any& Any::default_instance() {
|
||||
return *internal_default_instance();
|
||||
}
|
||||
|
||||
::google::protobuf::internal::ExplicitlyConstructed<Any> Any_default_instance_;
|
||||
|
||||
Any* Any::New(::google::protobuf::Arena* arena) const {
|
||||
Any* n = new Any;
|
||||
if (arena != NULL) {
|
||||
@ -218,11 +214,11 @@ bool Any::MergePartialFromCodedStream(
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:google.protobuf.Any)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
case 1: {
|
||||
if (tag == 10) {
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
|
||||
@ -234,20 +230,17 @@ bool Any::MergePartialFromCodedStream(
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(18)) goto parse_value;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
case 2: {
|
||||
if (tag == 18) {
|
||||
parse_value:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
|
||||
input, this->mutable_value()));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -275,7 +268,7 @@ failure:
|
||||
void Any::SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const {
|
||||
// @@protoc_insertion_point(serialize_start:google.protobuf.Any)
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
if (this->type_url().size() > 0) {
|
||||
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
|
||||
this->type_url().data(), this->type_url().length(),
|
||||
@ -285,7 +278,7 @@ void Any::SerializeWithCachedSizes(
|
||||
1, this->type_url(), output);
|
||||
}
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
if (this->value().size() > 0) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
|
||||
2, this->value(), output);
|
||||
@ -298,7 +291,7 @@ void Any::SerializeWithCachedSizes(
|
||||
bool deterministic, ::google::protobuf::uint8* target) const {
|
||||
(void)deterministic; // Unused
|
||||
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
if (this->type_url().size() > 0) {
|
||||
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
|
||||
this->type_url().data(), this->type_url().length(),
|
||||
@ -309,7 +302,7 @@ void Any::SerializeWithCachedSizes(
|
||||
1, this->type_url(), target);
|
||||
}
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
if (this->value().size() > 0) {
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
|
||||
@ -324,14 +317,14 @@ size_t Any::ByteSizeLong() const {
|
||||
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any)
|
||||
size_t total_size = 0;
|
||||
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
if (this->type_url().size() > 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::StringSize(
|
||||
this->type_url());
|
||||
}
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
if (this->value().size() > 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::BytesSize(
|
||||
@ -347,7 +340,7 @@ size_t Any::ByteSizeLong() const {
|
||||
|
||||
void Any::MergeFrom(const ::google::protobuf::Message& from) {
|
||||
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
|
||||
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
|
||||
GOOGLE_DCHECK_NE(&from, this);
|
||||
const Any* source =
|
||||
::google::protobuf::internal::DynamicCastToGenerated<const Any>(
|
||||
&from);
|
||||
@ -356,21 +349,14 @@ void Any::MergeFrom(const ::google::protobuf::Message& from) {
|
||||
::google::protobuf::internal::ReflectionOps::Merge(from, this);
|
||||
} else {
|
||||
// @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Any)
|
||||
UnsafeMergeFrom(*source);
|
||||
MergeFrom(*source);
|
||||
}
|
||||
}
|
||||
|
||||
void Any::MergeFrom(const Any& from) {
|
||||
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
|
||||
if (GOOGLE_PREDICT_TRUE(&from != this)) {
|
||||
UnsafeMergeFrom(from);
|
||||
} else {
|
||||
MergeFromFail(__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
void Any::UnsafeMergeFrom(const Any& from) {
|
||||
GOOGLE_DCHECK(&from != this);
|
||||
GOOGLE_DCHECK_NE(&from, this);
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
if (from.type_url().size() > 0) {
|
||||
|
||||
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
|
||||
@ -392,11 +378,10 @@ void Any::CopyFrom(const Any& from) {
|
||||
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Any)
|
||||
if (&from == this) return;
|
||||
Clear();
|
||||
UnsafeMergeFrom(from);
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
bool Any::IsInitialized() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -407,28 +392,24 @@ void Any::Swap(Any* other) {
|
||||
void Any::InternalSwap(Any* other) {
|
||||
type_url_.Swap(&other->type_url_);
|
||||
value_.Swap(&other->value_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata Any::GetMetadata() const {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
::google::protobuf::Metadata metadata;
|
||||
metadata.descriptor = Any_descriptor_;
|
||||
metadata.reflection = Any_reflection_;
|
||||
return metadata;
|
||||
return file_level_metadata[0];
|
||||
}
|
||||
|
||||
#if PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// Any
|
||||
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
void Any::clear_type_url() {
|
||||
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
const ::std::string& Any::type_url() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Any.type_url)
|
||||
return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return type_url_.GetNoArena();
|
||||
}
|
||||
void Any::set_type_url(const ::std::string& value) {
|
||||
|
||||
@ -466,13 +447,13 @@ void Any::set_allocated_type_url(::std::string* type_url) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url)
|
||||
}
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
void Any::clear_value() {
|
||||
value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
const ::std::string& Any::value() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Any.value)
|
||||
return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return value_.GetNoArena();
|
||||
}
|
||||
void Any::set_value(const ::std::string& value) {
|
||||
|
||||
@ -510,9 +491,6 @@ void Any::set_allocated_value(::std::string* value) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value)
|
||||
}
|
||||
|
||||
inline const Any* Any::internal_default_instance() {
|
||||
return &Any_default_instance_.get();
|
||||
}
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
@ -24,11 +24,18 @@
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
#include <google/protobuf/metadata.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/repeated_field.h>
|
||||
#include <google/protobuf/extension_set.h>
|
||||
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
|
||||
#include <google/protobuf/extension_set.h> // IWYU pragma: export
|
||||
#include <google/protobuf/unknown_field_set.h>
|
||||
#include <google/protobuf/any.h>
|
||||
// @@protoc_insertion_point(includes)
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class Any;
|
||||
class AnyDefaultTypeInternal;
|
||||
extern AnyDefaultTypeInternal _Any_default_instance_;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -36,10 +43,6 @@ namespace protobuf {
|
||||
// Internal implementation detail -- do not call these.
|
||||
void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
|
||||
void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto();
|
||||
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto();
|
||||
void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto();
|
||||
|
||||
class Any;
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@ -58,7 +61,10 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
static const ::google::protobuf::Descriptor* descriptor();
|
||||
static const Any& default_instance();
|
||||
|
||||
static const Any* internal_default_instance();
|
||||
static inline const Any* internal_default_instance() {
|
||||
return reinterpret_cast<const Any*>(
|
||||
&_Any_default_instance_);
|
||||
}
|
||||
|
||||
// implements Any -----------------------------------------------
|
||||
|
||||
@ -74,49 +80,49 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Any* New() const { return New(NULL); }
|
||||
inline Any* New() const PROTOBUF_FINAL { return New(NULL); }
|
||||
|
||||
Any* New(::google::protobuf::Arena* arena) const;
|
||||
void CopyFrom(const ::google::protobuf::Message& from);
|
||||
void MergeFrom(const ::google::protobuf::Message& from);
|
||||
Any* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const Any& from);
|
||||
void MergeFrom(const Any& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
|
||||
size_t ByteSizeLong() const;
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* output) const;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
|
||||
const PROTOBUF_FINAL {
|
||||
return InternalSerializeWithCachedSizesToArray(false, output);
|
||||
}
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void InternalSwap(Any* other);
|
||||
void UnsafeMergeFrom(const Any& from);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
return _internal_metadata_.arena();
|
||||
return NULL;
|
||||
}
|
||||
inline void* MaybeArenaPtr() const {
|
||||
return _internal_metadata_.raw_arena_ptr();
|
||||
return NULL;
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const;
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
void clear_type_url();
|
||||
static const int kTypeUrlFieldNumber = 1;
|
||||
const ::std::string& type_url() const;
|
||||
@ -127,7 +133,7 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
::std::string* release_type_url();
|
||||
void set_allocated_type_url(::std::string* type_url);
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
void clear_value();
|
||||
static const int kValueFieldNumber = 2;
|
||||
const ::std::string& value() const;
|
||||
@ -148,13 +154,10 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
::google::protobuf::internal::AnyMetadata _any_metadata_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_impl();
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto_impl();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto();
|
||||
friend const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fany_2eproto();
|
||||
friend void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
};
|
||||
extern ::google::protobuf::internal::ExplicitlyConstructed<Any> Any_default_instance_;
|
||||
|
||||
// ===================================================================
|
||||
|
||||
|
||||
@ -163,13 +166,13 @@ extern ::google::protobuf::internal::ExplicitlyConstructed<Any> Any_default_inst
|
||||
#if !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// Any
|
||||
|
||||
// optional string type_url = 1;
|
||||
// string type_url = 1;
|
||||
inline void Any::clear_type_url() {
|
||||
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Any::type_url() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Any.type_url)
|
||||
return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return type_url_.GetNoArena();
|
||||
}
|
||||
inline void Any::set_type_url(const ::std::string& value) {
|
||||
|
||||
@ -207,13 +210,13 @@ inline void Any::set_allocated_type_url(::std::string* type_url) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url)
|
||||
}
|
||||
|
||||
// optional bytes value = 2;
|
||||
// bytes value = 2;
|
||||
inline void Any::clear_value() {
|
||||
value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Any::value() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Any.value)
|
||||
return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return value_.GetNoArena();
|
||||
}
|
||||
inline void Any::set_value(const ::std::string& value) {
|
||||
|
||||
@ -251,13 +254,11 @@ inline void Any::set_allocated_value(::std::string* value) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value)
|
||||
}
|
||||
|
||||
inline const Any* Any::internal_default_instance() {
|
||||
return &Any_default_instance_.get();
|
||||
}
|
||||
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,12 +24,43 @@
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
#include <google/protobuf/metadata.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/repeated_field.h>
|
||||
#include <google/protobuf/extension_set.h>
|
||||
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
|
||||
#include <google/protobuf/extension_set.h> // IWYU pragma: export
|
||||
#include <google/protobuf/unknown_field_set.h>
|
||||
#include <google/protobuf/source_context.pb.h>
|
||||
#include <google/protobuf/type.pb.h>
|
||||
// @@protoc_insertion_point(includes)
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class Api;
|
||||
class ApiDefaultTypeInternal;
|
||||
extern ApiDefaultTypeInternal _Api_default_instance_;
|
||||
class Enum;
|
||||
class EnumDefaultTypeInternal;
|
||||
extern EnumDefaultTypeInternal _Enum_default_instance_;
|
||||
class EnumValue;
|
||||
class EnumValueDefaultTypeInternal;
|
||||
extern EnumValueDefaultTypeInternal _EnumValue_default_instance_;
|
||||
class Field;
|
||||
class FieldDefaultTypeInternal;
|
||||
extern FieldDefaultTypeInternal _Field_default_instance_;
|
||||
class Method;
|
||||
class MethodDefaultTypeInternal;
|
||||
extern MethodDefaultTypeInternal _Method_default_instance_;
|
||||
class Mixin;
|
||||
class MixinDefaultTypeInternal;
|
||||
extern MixinDefaultTypeInternal _Mixin_default_instance_;
|
||||
class Option;
|
||||
class OptionDefaultTypeInternal;
|
||||
extern OptionDefaultTypeInternal _Option_default_instance_;
|
||||
class SourceContext;
|
||||
class SourceContextDefaultTypeInternal;
|
||||
extern SourceContextDefaultTypeInternal _SourceContext_default_instance_;
|
||||
class Type;
|
||||
class TypeDefaultTypeInternal;
|
||||
extern TypeDefaultTypeInternal _Type_default_instance_;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -37,12 +68,6 @@ namespace protobuf {
|
||||
// Internal implementation detail -- do not call these.
|
||||
void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fapi_2eproto();
|
||||
void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
|
||||
|
||||
class Api;
|
||||
class Method;
|
||||
class Mixin;
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@ -61,55 +86,58 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
static const ::google::protobuf::Descriptor* descriptor();
|
||||
static const Api& default_instance();
|
||||
|
||||
static const Api* internal_default_instance();
|
||||
static inline const Api* internal_default_instance() {
|
||||
return reinterpret_cast<const Api*>(
|
||||
&_Api_default_instance_);
|
||||
}
|
||||
|
||||
void Swap(Api* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Api* New() const { return New(NULL); }
|
||||
inline Api* New() const PROTOBUF_FINAL { return New(NULL); }
|
||||
|
||||
Api* New(::google::protobuf::Arena* arena) const;
|
||||
void CopyFrom(const ::google::protobuf::Message& from);
|
||||
void MergeFrom(const ::google::protobuf::Message& from);
|
||||
Api* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const Api& from);
|
||||
void MergeFrom(const Api& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
|
||||
size_t ByteSizeLong() const;
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* output) const;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
|
||||
const PROTOBUF_FINAL {
|
||||
return InternalSerializeWithCachedSizesToArray(false, output);
|
||||
}
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void InternalSwap(Api* other);
|
||||
void UnsafeMergeFrom(const Api& from);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
return _internal_metadata_.arena();
|
||||
return NULL;
|
||||
}
|
||||
inline void* MaybeArenaPtr() const {
|
||||
return _internal_metadata_.raw_arena_ptr();
|
||||
return NULL;
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const;
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional string name = 1;
|
||||
// string name = 1;
|
||||
void clear_name();
|
||||
static const int kNameFieldNumber = 1;
|
||||
const ::std::string& name() const;
|
||||
@ -144,7 +172,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
|
||||
options() const;
|
||||
|
||||
// optional string version = 4;
|
||||
// string version = 4;
|
||||
void clear_version();
|
||||
static const int kVersionFieldNumber = 4;
|
||||
const ::std::string& version() const;
|
||||
@ -155,7 +183,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
::std::string* release_version();
|
||||
void set_allocated_version(::std::string* version);
|
||||
|
||||
// optional .google.protobuf.SourceContext source_context = 5;
|
||||
// .google.protobuf.SourceContext source_context = 5;
|
||||
bool has_source_context() const;
|
||||
void clear_source_context();
|
||||
static const int kSourceContextFieldNumber = 5;
|
||||
@ -176,7 +204,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
|
||||
mixins() const;
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
// .google.protobuf.Syntax syntax = 7;
|
||||
void clear_syntax();
|
||||
static const int kSyntaxFieldNumber = 7;
|
||||
::google::protobuf::Syntax syntax() const;
|
||||
@ -196,13 +224,10 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fapi_2eproto_impl();
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto_impl();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
};
|
||||
extern ::google::protobuf::internal::ExplicitlyConstructed<Api> Api_default_instance_;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ {
|
||||
@ -220,55 +245,58 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
static const ::google::protobuf::Descriptor* descriptor();
|
||||
static const Method& default_instance();
|
||||
|
||||
static const Method* internal_default_instance();
|
||||
static inline const Method* internal_default_instance() {
|
||||
return reinterpret_cast<const Method*>(
|
||||
&_Method_default_instance_);
|
||||
}
|
||||
|
||||
void Swap(Method* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Method* New() const { return New(NULL); }
|
||||
inline Method* New() const PROTOBUF_FINAL { return New(NULL); }
|
||||
|
||||
Method* New(::google::protobuf::Arena* arena) const;
|
||||
void CopyFrom(const ::google::protobuf::Message& from);
|
||||
void MergeFrom(const ::google::protobuf::Message& from);
|
||||
Method* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const Method& from);
|
||||
void MergeFrom(const Method& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
|
||||
size_t ByteSizeLong() const;
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* output) const;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
|
||||
const PROTOBUF_FINAL {
|
||||
return InternalSerializeWithCachedSizesToArray(false, output);
|
||||
}
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void InternalSwap(Method* other);
|
||||
void UnsafeMergeFrom(const Method& from);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
return _internal_metadata_.arena();
|
||||
return NULL;
|
||||
}
|
||||
inline void* MaybeArenaPtr() const {
|
||||
return _internal_metadata_.raw_arena_ptr();
|
||||
return NULL;
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const;
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional string name = 1;
|
||||
// string name = 1;
|
||||
void clear_name();
|
||||
static const int kNameFieldNumber = 1;
|
||||
const ::std::string& name() const;
|
||||
@ -279,7 +307,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
::std::string* release_name();
|
||||
void set_allocated_name(::std::string* name);
|
||||
|
||||
// optional string request_type_url = 2;
|
||||
// string request_type_url = 2;
|
||||
void clear_request_type_url();
|
||||
static const int kRequestTypeUrlFieldNumber = 2;
|
||||
const ::std::string& request_type_url() const;
|
||||
@ -290,13 +318,13 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
::std::string* release_request_type_url();
|
||||
void set_allocated_request_type_url(::std::string* request_type_url);
|
||||
|
||||
// optional bool request_streaming = 3;
|
||||
// bool request_streaming = 3;
|
||||
void clear_request_streaming();
|
||||
static const int kRequestStreamingFieldNumber = 3;
|
||||
bool request_streaming() const;
|
||||
void set_request_streaming(bool value);
|
||||
|
||||
// optional string response_type_url = 4;
|
||||
// string response_type_url = 4;
|
||||
void clear_response_type_url();
|
||||
static const int kResponseTypeUrlFieldNumber = 4;
|
||||
const ::std::string& response_type_url() const;
|
||||
@ -307,7 +335,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
::std::string* release_response_type_url();
|
||||
void set_allocated_response_type_url(::std::string* response_type_url);
|
||||
|
||||
// optional bool response_streaming = 5;
|
||||
// bool response_streaming = 5;
|
||||
void clear_response_streaming();
|
||||
static const int kResponseStreamingFieldNumber = 5;
|
||||
bool response_streaming() const;
|
||||
@ -325,7 +353,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
|
||||
options() const;
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
// .google.protobuf.Syntax syntax = 7;
|
||||
void clear_syntax();
|
||||
static const int kSyntaxFieldNumber = 7;
|
||||
::google::protobuf::Syntax syntax() const;
|
||||
@ -345,13 +373,10 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fapi_2eproto_impl();
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto_impl();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
};
|
||||
extern ::google::protobuf::internal::ExplicitlyConstructed<Method> Method_default_instance_;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ {
|
||||
@ -369,55 +394,58 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
static const ::google::protobuf::Descriptor* descriptor();
|
||||
static const Mixin& default_instance();
|
||||
|
||||
static const Mixin* internal_default_instance();
|
||||
static inline const Mixin* internal_default_instance() {
|
||||
return reinterpret_cast<const Mixin*>(
|
||||
&_Mixin_default_instance_);
|
||||
}
|
||||
|
||||
void Swap(Mixin* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Mixin* New() const { return New(NULL); }
|
||||
inline Mixin* New() const PROTOBUF_FINAL { return New(NULL); }
|
||||
|
||||
Mixin* New(::google::protobuf::Arena* arena) const;
|
||||
void CopyFrom(const ::google::protobuf::Message& from);
|
||||
void MergeFrom(const ::google::protobuf::Message& from);
|
||||
Mixin* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const Mixin& from);
|
||||
void MergeFrom(const Mixin& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
|
||||
size_t ByteSizeLong() const;
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* output) const;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
|
||||
const PROTOBUF_FINAL {
|
||||
return InternalSerializeWithCachedSizesToArray(false, output);
|
||||
}
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void InternalSwap(Mixin* other);
|
||||
void UnsafeMergeFrom(const Mixin& from);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
return _internal_metadata_.arena();
|
||||
return NULL;
|
||||
}
|
||||
inline void* MaybeArenaPtr() const {
|
||||
return _internal_metadata_.raw_arena_ptr();
|
||||
return NULL;
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const;
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional string name = 1;
|
||||
// string name = 1;
|
||||
void clear_name();
|
||||
static const int kNameFieldNumber = 1;
|
||||
const ::std::string& name() const;
|
||||
@ -428,7 +456,7 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
::std::string* release_name();
|
||||
void set_allocated_name(::std::string* name);
|
||||
|
||||
// optional string root = 2;
|
||||
// string root = 2;
|
||||
void clear_root();
|
||||
static const int kRootFieldNumber = 2;
|
||||
const ::std::string& root() const;
|
||||
@ -448,13 +476,10 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fapi_2eproto_impl();
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto_impl();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
};
|
||||
extern ::google::protobuf::internal::ExplicitlyConstructed<Mixin> Mixin_default_instance_;
|
||||
|
||||
// ===================================================================
|
||||
|
||||
|
||||
@ -463,13 +488,13 @@ extern ::google::protobuf::internal::ExplicitlyConstructed<Mixin> Mixin_default_
|
||||
#if !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// Api
|
||||
|
||||
// optional string name = 1;
|
||||
// string name = 1;
|
||||
inline void Api::clear_name() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Api::name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.name)
|
||||
return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return name_.GetNoArena();
|
||||
}
|
||||
inline void Api::set_name(const ::std::string& value) {
|
||||
|
||||
@ -567,13 +592,13 @@ Api::options() const {
|
||||
return options_;
|
||||
}
|
||||
|
||||
// optional string version = 4;
|
||||
// string version = 4;
|
||||
inline void Api::clear_version() {
|
||||
version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Api::version() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.version)
|
||||
return version_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return version_.GetNoArena();
|
||||
}
|
||||
inline void Api::set_version(const ::std::string& value) {
|
||||
|
||||
@ -611,7 +636,7 @@ inline void Api::set_allocated_version(::std::string* version) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version)
|
||||
}
|
||||
|
||||
// optional .google.protobuf.SourceContext source_context = 5;
|
||||
// .google.protobuf.SourceContext source_context = 5;
|
||||
inline bool Api::has_source_context() const {
|
||||
return this != internal_default_instance() && source_context_ != NULL;
|
||||
}
|
||||
@ -680,7 +705,7 @@ Api::mixins() const {
|
||||
return mixins_;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
// .google.protobuf.Syntax syntax = 7;
|
||||
inline void Api::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
@ -694,20 +719,17 @@ inline void Api::set_syntax(::google::protobuf::Syntax value) {
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
|
||||
}
|
||||
|
||||
inline const Api* Api::internal_default_instance() {
|
||||
return &Api_default_instance_.get();
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Method
|
||||
|
||||
// optional string name = 1;
|
||||
// string name = 1;
|
||||
inline void Method::clear_name() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Method::name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Method.name)
|
||||
return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return name_.GetNoArena();
|
||||
}
|
||||
inline void Method::set_name(const ::std::string& value) {
|
||||
|
||||
@ -745,13 +767,13 @@ inline void Method::set_allocated_name(::std::string* name) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name)
|
||||
}
|
||||
|
||||
// optional string request_type_url = 2;
|
||||
// string request_type_url = 2;
|
||||
inline void Method::clear_request_type_url() {
|
||||
request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Method::request_type_url() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url)
|
||||
return request_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return request_type_url_.GetNoArena();
|
||||
}
|
||||
inline void Method::set_request_type_url(const ::std::string& value) {
|
||||
|
||||
@ -789,7 +811,7 @@ inline void Method::set_allocated_request_type_url(::std::string* request_type_u
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url)
|
||||
}
|
||||
|
||||
// optional bool request_streaming = 3;
|
||||
// bool request_streaming = 3;
|
||||
inline void Method::clear_request_streaming() {
|
||||
request_streaming_ = false;
|
||||
}
|
||||
@ -803,13 +825,13 @@ inline void Method::set_request_streaming(bool value) {
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming)
|
||||
}
|
||||
|
||||
// optional string response_type_url = 4;
|
||||
// string response_type_url = 4;
|
||||
inline void Method::clear_response_type_url() {
|
||||
response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Method::response_type_url() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url)
|
||||
return response_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return response_type_url_.GetNoArena();
|
||||
}
|
||||
inline void Method::set_response_type_url(const ::std::string& value) {
|
||||
|
||||
@ -847,7 +869,7 @@ inline void Method::set_allocated_response_type_url(::std::string* response_type
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url)
|
||||
}
|
||||
|
||||
// optional bool response_streaming = 5;
|
||||
// bool response_streaming = 5;
|
||||
inline void Method::clear_response_streaming() {
|
||||
response_streaming_ = false;
|
||||
}
|
||||
@ -891,7 +913,7 @@ Method::options() const {
|
||||
return options_;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
// .google.protobuf.Syntax syntax = 7;
|
||||
inline void Method::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
@ -905,20 +927,17 @@ inline void Method::set_syntax(::google::protobuf::Syntax value) {
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
|
||||
}
|
||||
|
||||
inline const Method* Method::internal_default_instance() {
|
||||
return &Method_default_instance_.get();
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Mixin
|
||||
|
||||
// optional string name = 1;
|
||||
// string name = 1;
|
||||
inline void Mixin::clear_name() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Mixin::name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
|
||||
return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return name_.GetNoArena();
|
||||
}
|
||||
inline void Mixin::set_name(const ::std::string& value) {
|
||||
|
||||
@ -956,13 +975,13 @@ inline void Mixin::set_allocated_name(::std::string* name) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
// string root = 2;
|
||||
inline void Mixin::clear_root() {
|
||||
root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Mixin::root() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
|
||||
return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
return root_.GetNoArena();
|
||||
}
|
||||
inline void Mixin::set_root(const ::std::string& value) {
|
||||
|
||||
@ -1000,9 +1019,6 @@ inline void Mixin::set_allocated_root(::std::string* root) {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
|
||||
}
|
||||
|
||||
inline const Mixin* Mixin::internal_default_instance() {
|
||||
return &Mixin_default_instance_.get();
|
||||
}
|
||||
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@ -1011,6 +1027,7 @@ inline const Mixin* Mixin::internal_default_instance() {
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
|
@ -40,6 +40,7 @@ option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "ApiProto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
option go_package = "google.golang.org/genproto/protobuf/api;api";
|
||||
|
||||
// Api is a light-weight descriptor for a protocol buffer service.
|
||||
message Api {
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
#endif // ADDRESS_SANITIZER
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -141,7 +141,7 @@ Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n,
|
||||
// malloc but it's not yet usable until we return it as part of an allocation.
|
||||
ASAN_POISON_MEMORY_REGION(
|
||||
reinterpret_cast<char*>(b) + b->pos, b->size - b->pos);
|
||||
#endif
|
||||
#endif // ADDRESS_SANITIZER
|
||||
return b;
|
||||
}
|
||||
|
||||
@ -205,7 +205,7 @@ void* Arena::AllocFromBlock(Block* b, size_t n) {
|
||||
b->pos = p + n;
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b) + p, n);
|
||||
#endif
|
||||
#endif // ADDRESS_SANITIZER
|
||||
return reinterpret_cast<char*>(b) + p;
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ uint64 Arena::SpaceUsed() const {
|
||||
return space_used;
|
||||
}
|
||||
|
||||
pair<uint64, uint64> Arena::SpaceAllocatedAndUsed() const {
|
||||
std::pair<uint64, uint64> Arena::SpaceAllocatedAndUsed() const {
|
||||
uint64 allocated = 0;
|
||||
uint64 used = 0;
|
||||
|
||||
@ -265,9 +265,19 @@ uint64 Arena::FreeBlocks() {
|
||||
space_allocated += (b->size);
|
||||
Block* next = b->next;
|
||||
if (next != NULL) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
// This memory was provided by the underlying allocator as unpoisoned, so
|
||||
// return it in an unpoisoned state.
|
||||
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b), b->size);
|
||||
#endif // ADDRESS_SANITIZER
|
||||
options_.block_dealloc(b, b->size);
|
||||
} else {
|
||||
if (owns_first_block_) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
// This memory was provided by the underlying allocator as unpoisoned,
|
||||
// so return it in an unpoisoned state.
|
||||
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b), b->size);
|
||||
#endif // ADDRESS_SANITIZER
|
||||
options_.block_dealloc(b, b->size);
|
||||
} else {
|
||||
// User passed in the first block, skip free'ing the memory.
|
||||
|
@ -31,9 +31,40 @@
|
||||
#ifndef GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
|
||||
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/arena.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
template <typename T, bool use_arena>
|
||||
void TestParseCorruptedString(const T& message) {
|
||||
int success_count = 0;
|
||||
string s = message.SerializeAsString();
|
||||
const int kMaxIters = 900;
|
||||
const int stride = s.size() <= kMaxIters ? 1 : s.size() / kMaxIters;
|
||||
const int start = stride == 1 || use_arena ? 0 : (stride + 1) / 2;
|
||||
for (int i = start; i < s.size(); i += stride) {
|
||||
for (int c = 1 + (i % 17); c < 256; c += 2 * c + (i & 3)) {
|
||||
s[i] ^= c;
|
||||
google::protobuf::Arena arena;
|
||||
T* message =
|
||||
google::protobuf::Arena::CreateMessage<T>(use_arena ? &arena : NULL);
|
||||
if (message->ParseFromString(s)) {
|
||||
++success_count;
|
||||
}
|
||||
if (!use_arena) {
|
||||
delete message;
|
||||
}
|
||||
s[i] ^= c; // Restore s to its original state.
|
||||
}
|
||||
}
|
||||
// This next line is a low bar. But getting through the test without crashing
|
||||
// due to use-after-free or other bugs is a big part of what we're checking.
|
||||
GOOGLE_CHECK_GT(success_count, 0);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
class NoHeapChecker {
|
||||
|
@ -249,7 +249,7 @@ TEST(ArenaTest, Parsing) {
|
||||
arena_message->ParseFromString(original.SerializeAsString());
|
||||
TestUtil::ExpectAllFieldsSet(*arena_message);
|
||||
|
||||
// Test that string fields have null terminator bytes (earlier bug).
|
||||
// Test that string fields have nul terminator bytes (earlier bug).
|
||||
EXPECT_EQ(strlen(original.optional_string().c_str()),
|
||||
strlen(arena_message->optional_string().c_str()));
|
||||
}
|
||||
@ -1154,6 +1154,13 @@ TEST(ArenaTest, NoHeapAllocationsTest) {
|
||||
arena.Reset();
|
||||
}
|
||||
|
||||
TEST(ArenaTest, ParseCorruptedString) {
|
||||
TestAllTypes message;
|
||||
TestUtil::SetAllFields(&message);
|
||||
TestParseCorruptedString<TestAllTypes, true>(message);
|
||||
TestParseCorruptedString<TestAllTypes, false>(message);
|
||||
}
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_NO_RTTI
|
||||
// Test construction on an arena via generic MessageLite interface. We should be
|
||||
// able to successfully deserialize on the arena without incurring heap
|
||||
|
@ -44,7 +44,7 @@ void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
|
||||
const ::std::string* other = *value.UnsafeRawStringPointer();
|
||||
// If the pointers are the same then do nothing.
|
||||
if (me != other) {
|
||||
SetNoArena(default_value, value.GetNoArena(default_value));
|
||||
SetNoArena(default_value, value.GetNoArena());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/fastmem.h>
|
||||
#include <google/protobuf/arena.h>
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
|
||||
|
||||
|
||||
@ -64,9 +63,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
}
|
||||
|
||||
// Basic accessors.
|
||||
inline const ::std::string& Get(const ::std::string* /* default_value */) const {
|
||||
return *ptr_;
|
||||
}
|
||||
inline const ::std::string& Get() const { return *ptr_; }
|
||||
|
||||
inline ::std::string* Mutable(const ::std::string* default_value,
|
||||
::google::protobuf::Arena* arena) {
|
||||
@ -150,13 +147,12 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
std::swap(ptr_, other->ptr_);
|
||||
}
|
||||
|
||||
// Frees storage (if not on an arena) and sets field to default value.
|
||||
// Frees storage (if not on an arena).
|
||||
inline void Destroy(const ::std::string* default_value,
|
||||
::google::protobuf::Arena* arena) {
|
||||
if (arena == NULL && ptr_ != default_value) {
|
||||
delete ptr_;
|
||||
}
|
||||
ptr_ = const_cast< ::std::string* >(default_value);
|
||||
}
|
||||
|
||||
// Clears content, but keeps allocated string if arena != NULL, to avoid the
|
||||
@ -216,9 +212,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
|
||||
void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value);
|
||||
|
||||
inline const ::std::string& GetNoArena(const ::std::string* /* default_value */) const {
|
||||
return *ptr_;
|
||||
}
|
||||
inline const ::std::string& GetNoArena() const { return *ptr_; }
|
||||
|
||||
inline ::std::string* MutableNoArena(const ::std::string* default_value) {
|
||||
if (ptr_ == default_value) {
|
||||
@ -253,7 +247,6 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
if (ptr_ != default_value) {
|
||||
delete ptr_;
|
||||
}
|
||||
ptr_ = NULL;
|
||||
}
|
||||
|
||||
inline void ClearToEmptyNoArena(const ::std::string* default_value) {
|
||||
@ -281,6 +274,10 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
return &ptr_;
|
||||
}
|
||||
|
||||
inline bool IsDefault(const ::std::string* default_value) const {
|
||||
return ptr_ == default_value;
|
||||
}
|
||||
|
||||
private:
|
||||
::std::string* ptr_;
|
||||
|
||||
|
@ -59,11 +59,11 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnHeap) {
|
||||
ArenaStringPtr field;
|
||||
::std::string default_value = "default";
|
||||
field.UnsafeSetDefault(&default_value);
|
||||
EXPECT_EQ(string("default"), field.Get(&default_value));
|
||||
EXPECT_EQ(string("default"), field.Get());
|
||||
field.Set(&default_value, WrapString("Test short"), NULL);
|
||||
EXPECT_EQ(string("Test short"), field.Get(&default_value));
|
||||
EXPECT_EQ(string("Test short"), field.Get());
|
||||
field.Set(&default_value, WrapString("Test long long long long value"), NULL);
|
||||
EXPECT_EQ(string("Test long long long long value"), field.Get(&default_value));
|
||||
EXPECT_EQ(string("Test long long long long value"), field.Get());
|
||||
field.Set(&default_value, string(""), NULL);
|
||||
field.Destroy(&default_value, NULL);
|
||||
|
||||
@ -71,11 +71,11 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnHeap) {
|
||||
field2.UnsafeSetDefault(&default_value);
|
||||
::std::string* mut = field2.Mutable(&default_value, NULL);
|
||||
EXPECT_EQ(mut, field2.Mutable(&default_value, NULL));
|
||||
EXPECT_EQ(mut, &field2.Get(&default_value));
|
||||
EXPECT_EQ(mut, &field2.Get());
|
||||
EXPECT_NE(&default_value, mut);
|
||||
EXPECT_EQ(string("default"), *mut);
|
||||
*mut = "Test long long long long value"; // ensure string allocates storage
|
||||
EXPECT_EQ(string("Test long long long long value"), field2.Get(&default_value));
|
||||
EXPECT_EQ(string("Test long long long long value"), field2.Get());
|
||||
field2.Destroy(&default_value, NULL);
|
||||
}
|
||||
|
||||
@ -84,12 +84,11 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) {
|
||||
ArenaStringPtr field;
|
||||
::std::string default_value = "default";
|
||||
field.UnsafeSetDefault(&default_value);
|
||||
EXPECT_EQ(string("default"), field.Get(&default_value));
|
||||
EXPECT_EQ(string("default"), field.Get());
|
||||
field.Set(&default_value, WrapString("Test short"), &arena);
|
||||
EXPECT_EQ(string("Test short"), field.Get(&default_value));
|
||||
EXPECT_EQ(string("Test short"), field.Get());
|
||||
field.Set(&default_value, WrapString("Test long long long long value"), &arena);
|
||||
EXPECT_EQ(string("Test long long long long value"),
|
||||
field.Get(&default_value));
|
||||
EXPECT_EQ(string("Test long long long long value"), field.Get());
|
||||
field.Set(&default_value, string(""), &arena);
|
||||
field.Destroy(&default_value, &arena);
|
||||
|
||||
@ -97,12 +96,11 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) {
|
||||
field2.UnsafeSetDefault(&default_value);
|
||||
::std::string* mut = field2.Mutable(&default_value, &arena);
|
||||
EXPECT_EQ(mut, field2.Mutable(&default_value, &arena));
|
||||
EXPECT_EQ(mut, &field2.Get(&default_value));
|
||||
EXPECT_EQ(mut, &field2.Get());
|
||||
EXPECT_NE(&default_value, mut);
|
||||
EXPECT_EQ(string("default"), *mut);
|
||||
*mut = "Test long long long long value"; // ensure string allocates storage
|
||||
EXPECT_EQ(string("Test long long long long value"),
|
||||
field2.Get(&default_value));
|
||||
EXPECT_EQ(string("Test long long long long value"), field2.Get());
|
||||
field2.Destroy(&default_value, &arena);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace compiler {
|
||||
CodeGenerator::~CodeGenerator() {}
|
||||
|
||||
bool CodeGenerator::GenerateAll(
|
||||
const vector<const FileDescriptor*>& files,
|
||||
const std::vector<const FileDescriptor*>& files,
|
||||
const string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
string* error) const {
|
||||
@ -85,18 +85,18 @@ io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
|
||||
}
|
||||
|
||||
void GeneratorContext::ListParsedFiles(
|
||||
vector<const FileDescriptor*>* output) {
|
||||
std::vector<const FileDescriptor*>* output) {
|
||||
GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
|
||||
}
|
||||
|
||||
// Parses a set of comma-delimited name/value pairs.
|
||||
void ParseGeneratorParameter(const string& text,
|
||||
vector<pair<string, string> >* output) {
|
||||
vector<string> parts = Split(text, ",", true);
|
||||
std::vector<std::pair<string, string> >* output) {
|
||||
std::vector<string> parts = Split(text, ",", true);
|
||||
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
string::size_type equals_pos = parts[i].find_first_of('=');
|
||||
pair<string, string> value;
|
||||
std::pair<string, string> value;
|
||||
if (equals_pos == string::npos) {
|
||||
value.first = parts[i];
|
||||
value.second = "";
|
||||
|
@ -90,7 +90,7 @@ class LIBPROTOC_EXPORT CodeGenerator {
|
||||
//
|
||||
// Returns true if successful. Otherwise, sets *error to a description of
|
||||
// the problem (e.g. "invalid parameter") and returns false.
|
||||
virtual bool GenerateAll(const vector<const FileDescriptor*>& files,
|
||||
virtual bool GenerateAll(const std::vector<const FileDescriptor*>& files,
|
||||
const string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
string* error) const;
|
||||
@ -141,7 +141,7 @@ class LIBPROTOC_EXPORT GeneratorContext {
|
||||
// Returns a vector of FileDescriptors for all the files being compiled
|
||||
// in this run. Useful for languages, such as Go, that treat files
|
||||
// differently when compiled as a set rather than individually.
|
||||
virtual void ListParsedFiles(vector<const FileDescriptor*>* output);
|
||||
virtual void ListParsedFiles(std::vector<const FileDescriptor*>* output);
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
|
||||
@ -158,7 +158,7 @@ typedef GeneratorContext OutputDirectory;
|
||||
// parses to the pairs:
|
||||
// ("foo", "bar"), ("baz", ""), ("qux", "corge")
|
||||
extern void ParseGeneratorParameter(const string&,
|
||||
vector<pair<string, string> >*);
|
||||
std::vector<std::pair<string, string> >*);
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
|
@ -173,7 +173,8 @@ bool VerifyDirectoryExists(const string& path) {
|
||||
// directories listed in |filename|.
|
||||
bool TryCreateParentDirectory(const string& prefix, const string& filename) {
|
||||
// Recursively create parent directories to the output file.
|
||||
vector<string> parts = Split(filename, "/", true);
|
||||
std::vector<string> parts =
|
||||
Split(filename, "/", true);
|
||||
string path_so_far = prefix;
|
||||
for (int i = 0; i < parts.size() - 1; i++) {
|
||||
path_so_far += parts[i];
|
||||
@ -338,7 +339,7 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
|
||||
// them all to disk on demand.
|
||||
class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
|
||||
public:
|
||||
GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files);
|
||||
GeneratorContextImpl(const std::vector<const FileDescriptor*>& parsed_files);
|
||||
~GeneratorContextImpl();
|
||||
|
||||
// Write all files in the directory to disk at the given output location,
|
||||
@ -354,14 +355,14 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
|
||||
void AddJarManifest();
|
||||
|
||||
// Get name of all output files.
|
||||
void GetOutputFilenames(vector<string>* output_filenames);
|
||||
void GetOutputFilenames(std::vector<string>* output_filenames);
|
||||
|
||||
// implements GeneratorContext --------------------------------------
|
||||
io::ZeroCopyOutputStream* Open(const string& filename);
|
||||
io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
|
||||
io::ZeroCopyOutputStream* OpenForInsert(
|
||||
const string& filename, const string& insertion_point);
|
||||
void ListParsedFiles(vector<const FileDescriptor*>* output) {
|
||||
void ListParsedFiles(std::vector<const FileDescriptor*>* output) {
|
||||
*output = parsed_files_;
|
||||
}
|
||||
|
||||
@ -370,8 +371,8 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
|
||||
|
||||
// map instead of hash_map so that files are written in order (good when
|
||||
// writing zips).
|
||||
map<string, string*> files_;
|
||||
const vector<const FileDescriptor*>& parsed_files_;
|
||||
std::map<string, string*> files_;
|
||||
const std::vector<const FileDescriptor*>& parsed_files_;
|
||||
bool had_error_;
|
||||
};
|
||||
|
||||
@ -408,7 +409,7 @@ class CommandLineInterface::MemoryOutputStream
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl(
|
||||
const vector<const FileDescriptor*>& parsed_files)
|
||||
const std::vector<const FileDescriptor*>& parsed_files)
|
||||
: parsed_files_(parsed_files),
|
||||
had_error_(false) {
|
||||
}
|
||||
@ -427,7 +428,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
|
||||
return false;
|
||||
}
|
||||
|
||||
for (map<string, string*>::const_iterator iter = files_.begin();
|
||||
for (std::map<string, string*>::const_iterator iter = files_.begin();
|
||||
iter != files_.end(); ++iter) {
|
||||
const string& relative_filename = iter->first;
|
||||
const char* data = iter->second->data();
|
||||
@ -515,7 +516,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
|
||||
io::FileOutputStream stream(file_descriptor);
|
||||
ZipWriter zip_writer(&stream);
|
||||
|
||||
for (map<string, string*>::const_iterator iter = files_.begin();
|
||||
for (std::map<string, string*>::const_iterator iter = files_.begin();
|
||||
iter != files_.end(); ++iter) {
|
||||
zip_writer.Write(iter->first, *iter->second);
|
||||
}
|
||||
@ -544,8 +545,8 @@ void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
|
||||
}
|
||||
|
||||
void CommandLineInterface::GeneratorContextImpl::GetOutputFilenames(
|
||||
vector<string>* output_filenames) {
|
||||
for (map<string, string*>::iterator iter = files_.begin();
|
||||
std::vector<string>* output_filenames) {
|
||||
for (std::map<string, string*>::iterator iter = files_.begin();
|
||||
iter != files_.end(); ++iter) {
|
||||
output_filenames->push_back(iter->first);
|
||||
}
|
||||
@ -768,7 +769,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
||||
ErrorPrinter error_collector(error_format_, &source_tree);
|
||||
Importer importer(&source_tree, &error_collector);
|
||||
|
||||
vector<const FileDescriptor*> parsed_files;
|
||||
std::vector<const FileDescriptor*> parsed_files;
|
||||
|
||||
// Parse each file.
|
||||
for (int i = 0; i < input_files_.size(); i++) {
|
||||
@ -978,7 +979,7 @@ CommandLineInterface::ParseArgumentStatus
|
||||
CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
|
||||
executable_name_ = argv[0];
|
||||
|
||||
vector<string> arguments;
|
||||
std::vector<string> arguments;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
arguments.push_back(argv[i]);
|
||||
}
|
||||
@ -1012,7 +1013,7 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
|
||||
// Don't use make_pair as the old/default standard library on Solaris
|
||||
// doesn't support it without explicit template parameters, which are
|
||||
// incompatible with C++0x's make_pair.
|
||||
proto_path_.push_back(pair<string, string>("", "."));
|
||||
proto_path_.push_back(std::pair<string, string>("", "."));
|
||||
}
|
||||
|
||||
// Check some errror cases.
|
||||
@ -1135,7 +1136,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
// Java's -classpath (and some other languages) delimits path components
|
||||
// with colons. Let's accept that syntax too just to make things more
|
||||
// intuitive.
|
||||
vector<string> parts = Split(
|
||||
std::vector<string> parts = Split(
|
||||
value, kPathSeparator, true);
|
||||
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
@ -1172,19 +1173,21 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
// Don't use make_pair as the old/default standard library on Solaris
|
||||
// doesn't support it without explicit template parameters, which are
|
||||
// incompatible with C++0x's make_pair.
|
||||
proto_path_.push_back(pair<string, string>(virtual_path, disk_path));
|
||||
proto_path_.push_back(std::pair<string, string>(virtual_path, disk_path));
|
||||
}
|
||||
|
||||
} else if (name == "--direct_dependencies") {
|
||||
if (direct_dependencies_explicitly_set_) {
|
||||
std::cerr << name << " may only be passed once. To specify multiple "
|
||||
"direct dependencies, pass them all as a single "
|
||||
"parameter separated by ':'." << std::endl;
|
||||
"parameter separated by ':'."
|
||||
<< std::endl;
|
||||
return PARSE_ARGUMENT_FAIL;
|
||||
}
|
||||
|
||||
direct_dependencies_explicitly_set_ = true;
|
||||
vector<string> direct = Split(value, ":", true);
|
||||
std::vector<string> direct = Split(
|
||||
value, ":", true);
|
||||
GOOGLE_DCHECK(direct_dependencies_.empty());
|
||||
direct_dependencies_.insert(direct.begin(), direct.end());
|
||||
|
||||
@ -1451,7 +1454,7 @@ void CommandLineInterface::PrintHelpText() {
|
||||
}
|
||||
|
||||
bool CommandLineInterface::GenerateOutput(
|
||||
const vector<const FileDescriptor*>& parsed_files,
|
||||
const std::vector<const FileDescriptor*>& parsed_files,
|
||||
const OutputDirective& output_directive,
|
||||
GeneratorContext* generator_context) {
|
||||
// Call the generator.
|
||||
@ -1493,12 +1496,12 @@ bool CommandLineInterface::GenerateOutput(
|
||||
}
|
||||
|
||||
bool CommandLineInterface::GenerateDependencyManifestFile(
|
||||
const vector<const FileDescriptor*>& parsed_files,
|
||||
const std::vector<const FileDescriptor*>& parsed_files,
|
||||
const GeneratorContextMap& output_directories,
|
||||
DiskSourceTree* source_tree) {
|
||||
FileDescriptorSet file_set;
|
||||
|
||||
set<const FileDescriptor*> already_seen;
|
||||
std::set<const FileDescriptor*> already_seen;
|
||||
for (int i = 0; i < parsed_files.size(); i++) {
|
||||
GetTransitiveDependencies(parsed_files[i],
|
||||
false,
|
||||
@ -1507,12 +1510,12 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
|
||||
file_set.mutable_file());
|
||||
}
|
||||
|
||||
vector<string> output_filenames;
|
||||
std::vector<string> output_filenames;
|
||||
for (GeneratorContextMap::const_iterator iter = output_directories.begin();
|
||||
iter != output_directories.end(); ++iter) {
|
||||
const string& location = iter->first;
|
||||
GeneratorContextImpl* directory = iter->second;
|
||||
vector<string> relative_output_filenames;
|
||||
std::vector<string> relative_output_filenames;
|
||||
directory->GetOutputFilenames(&relative_output_filenames);
|
||||
for (int i = 0; i < relative_output_filenames.size(); i++) {
|
||||
string output_filename = location + relative_output_filenames[i];
|
||||
@ -1565,7 +1568,7 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
|
||||
}
|
||||
|
||||
bool CommandLineInterface::GeneratePluginOutput(
|
||||
const vector<const FileDescriptor*>& parsed_files,
|
||||
const std::vector<const FileDescriptor*>& parsed_files,
|
||||
const string& plugin_name,
|
||||
const string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
@ -1578,7 +1581,7 @@ bool CommandLineInterface::GeneratePluginOutput(
|
||||
request.set_parameter(parameter);
|
||||
}
|
||||
|
||||
set<const FileDescriptor*> already_seen;
|
||||
std::set<const FileDescriptor*> already_seen;
|
||||
for (int i = 0; i < parsed_files.size(); i++) {
|
||||
request.add_file_to_generate(parsed_files[i]->name());
|
||||
GetTransitiveDependencies(parsed_files[i],
|
||||
@ -1708,11 +1711,11 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
|
||||
}
|
||||
|
||||
bool CommandLineInterface::WriteDescriptorSet(
|
||||
const vector<const FileDescriptor*> parsed_files) {
|
||||
const std::vector<const FileDescriptor*> parsed_files) {
|
||||
FileDescriptorSet file_set;
|
||||
|
||||
if (imports_in_descriptor_set_) {
|
||||
set<const FileDescriptor*> already_seen;
|
||||
std::set<const FileDescriptor*> already_seen;
|
||||
for (int i = 0; i < parsed_files.size(); i++) {
|
||||
GetTransitiveDependencies(parsed_files[i],
|
||||
true, // Include json_name
|
||||
@ -1720,7 +1723,7 @@ bool CommandLineInterface::WriteDescriptorSet(
|
||||
&already_seen, file_set.mutable_file());
|
||||
}
|
||||
} else {
|
||||
set<const FileDescriptor*> already_seen;
|
||||
std::set<const FileDescriptor*> already_seen;
|
||||
for (int i = 0; i < parsed_files.size(); i++) {
|
||||
if (!already_seen.insert(parsed_files[i]).second) {
|
||||
continue;
|
||||
@ -1765,7 +1768,7 @@ void CommandLineInterface::GetTransitiveDependencies(
|
||||
const FileDescriptor* file,
|
||||
bool include_json_name,
|
||||
bool include_source_code_info,
|
||||
set<const FileDescriptor*>* already_seen,
|
||||
std::set<const FileDescriptor*>* already_seen,
|
||||
RepeatedPtrField<FileDescriptorProto>* output) {
|
||||
if (!already_seen->insert(file).second) {
|
||||
// Already saw this file. Skip.
|
||||
@ -1824,11 +1827,11 @@ namespace {
|
||||
// parameter will contain the direct children (when groups are ignored in the
|
||||
// tree) of the given descriptor for the caller to traverse. The declaration
|
||||
// order of the nested messages is also preserved.
|
||||
typedef pair<int, int> FieldRange;
|
||||
void GatherOccupiedFieldRanges(const Descriptor* descriptor,
|
||||
set<FieldRange>* ranges,
|
||||
vector<const Descriptor*>* nested_messages) {
|
||||
set<const Descriptor*> groups;
|
||||
typedef std::pair<int, int> FieldRange;
|
||||
void GatherOccupiedFieldRanges(
|
||||
const Descriptor* descriptor, std::set<FieldRange>* ranges,
|
||||
std::vector<const Descriptor*>* nested_messages) {
|
||||
std::set<const Descriptor*> groups;
|
||||
for (int i = 0; i < descriptor->field_count(); ++i) {
|
||||
const FieldDescriptor* fd = descriptor->field(i);
|
||||
ranges->insert(FieldRange(fd->number(), fd->number() + 1));
|
||||
@ -1860,11 +1863,11 @@ void GatherOccupiedFieldRanges(const Descriptor* descriptor,
|
||||
// Actually prints the formatted free field numbers for given message name and
|
||||
// occupied ranges.
|
||||
void FormatFreeFieldNumbers(const string& name,
|
||||
const set<FieldRange>& ranges) {
|
||||
const std::set<FieldRange>& ranges) {
|
||||
string output;
|
||||
StringAppendF(&output, "%-35s free:", name.c_str());
|
||||
int next_free_number = 1;
|
||||
for (set<FieldRange>::const_iterator i = ranges.begin();
|
||||
for (std::set<FieldRange>::const_iterator i = ranges.begin();
|
||||
i != ranges.end(); ++i) {
|
||||
// This happens when groups re-use parent field numbers, in which
|
||||
// case we skip the FieldRange entirely.
|
||||
@ -1891,8 +1894,8 @@ void FormatFreeFieldNumbers(const string& name,
|
||||
|
||||
void CommandLineInterface::PrintFreeFieldNumbers(
|
||||
const Descriptor* descriptor) {
|
||||
set<FieldRange> ranges;
|
||||
vector<const Descriptor*> nested_messages;
|
||||
std::set<FieldRange> ranges;
|
||||
std::vector<const Descriptor*> nested_messages;
|
||||
GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
|
||||
|
||||
for (int i = 0; i < nested_messages.size(); ++i) {
|
||||
|
@ -56,9 +56,7 @@ class FileDescriptorProto; // descriptor.pb.h
|
||||
template<typename T> class RepeatedPtrField; // repeated_field.h
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
|
||||
@ -240,24 +238,24 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
|
||||
// Generate the given output file from the given input.
|
||||
struct OutputDirective; // see below
|
||||
bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files,
|
||||
bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files,
|
||||
const OutputDirective& output_directive,
|
||||
GeneratorContext* generator_context);
|
||||
bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files,
|
||||
const string& plugin_name,
|
||||
const string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
string* error);
|
||||
bool GeneratePluginOutput(
|
||||
const std::vector<const FileDescriptor*>& parsed_files,
|
||||
const string& plugin_name, const string& parameter,
|
||||
GeneratorContext* generator_context, string* error);
|
||||
|
||||
// Implements --encode and --decode.
|
||||
bool EncodeOrDecode(const DescriptorPool* pool);
|
||||
|
||||
// Implements the --descriptor_set_out option.
|
||||
bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files);
|
||||
bool WriteDescriptorSet(
|
||||
const std::vector<const FileDescriptor*> parsed_files);
|
||||
|
||||
// Implements the --dependency_out option
|
||||
bool GenerateDependencyManifestFile(
|
||||
const vector<const FileDescriptor*>& parsed_files,
|
||||
const std::vector<const FileDescriptor*>& parsed_files,
|
||||
const GeneratorContextMap& output_directories,
|
||||
DiskSourceTree* source_tree);
|
||||
|
||||
@ -274,7 +272,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
const FileDescriptor* file,
|
||||
bool include_json_name,
|
||||
bool include_source_code_info,
|
||||
set<const FileDescriptor*>* already_seen,
|
||||
std::set<const FileDescriptor*>* already_seen,
|
||||
RepeatedPtrField<FileDescriptorProto>* output);
|
||||
|
||||
// Implements the --print_free_field_numbers. This function prints free field
|
||||
@ -308,14 +306,14 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
CodeGenerator* generator;
|
||||
string help_text;
|
||||
};
|
||||
typedef map<string, GeneratorInfo> GeneratorMap;
|
||||
typedef std::map<string, GeneratorInfo> GeneratorMap;
|
||||
GeneratorMap generators_by_flag_name_;
|
||||
GeneratorMap generators_by_option_name_;
|
||||
// A map from generator names to the parameters specified using the option
|
||||
// flag. For example, if the user invokes the compiler with:
|
||||
// protoc --foo_out=outputdir --foo_opt=enable_bar ...
|
||||
// Then there will be an entry ("--foo_out", "enable_bar") in this map.
|
||||
map<string, string> generator_parameters_;
|
||||
std::map<string, string> generator_parameters_;
|
||||
|
||||
// See AllowPlugins(). If this is empty, plugins aren't allowed.
|
||||
string plugin_prefix_;
|
||||
@ -323,7 +321,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
// Maps specific plugin names to files. When executing a plugin, this map
|
||||
// is searched first to find the plugin executable. If not found here, the
|
||||
// PATH (or other OS-specific search strategy) is searched.
|
||||
map<string, string> plugins_;
|
||||
std::map<string, string> plugins_;
|
||||
|
||||
// Stuff parsed from command line.
|
||||
enum Mode {
|
||||
@ -349,12 +347,13 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
|
||||
ErrorFormat error_format_;
|
||||
|
||||
vector<pair<string, string> > proto_path_; // Search path for proto files.
|
||||
vector<string> input_files_; // Names of the input proto files.
|
||||
std::vector<std::pair<string, string> >
|
||||
proto_path_; // Search path for proto files.
|
||||
std::vector<string> input_files_; // Names of the input proto files.
|
||||
|
||||
// Names of proto files which are allowed to be imported. Used by build
|
||||
// systems to enforce depend-on-what-you-import.
|
||||
set<string> direct_dependencies_;
|
||||
std::set<string> direct_dependencies_;
|
||||
bool direct_dependencies_explicitly_set_;
|
||||
|
||||
// output_directives_ lists all the files we are supposed to output and what
|
||||
@ -365,7 +364,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
string parameter;
|
||||
string output_location;
|
||||
};
|
||||
vector<OutputDirective> output_directives_;
|
||||
std::vector<OutputDirective> output_directives_;
|
||||
|
||||
// When using --encode or --decode, this names the type we are encoding or
|
||||
// decoding. (Empty string indicates --decode_raw.)
|
||||
|
@ -217,7 +217,7 @@ class CommandLineInterfaceTest : public testing::Test {
|
||||
string captured_stdout_;
|
||||
|
||||
// Pointers which need to be deleted later.
|
||||
vector<CodeGenerator*> mock_generators_to_delete_;
|
||||
std::vector<CodeGenerator*> mock_generators_to_delete_;
|
||||
|
||||
NullCodeGenerator* null_generator_;
|
||||
};
|
||||
@ -291,7 +291,7 @@ void CommandLineInterfaceTest::TearDown() {
|
||||
}
|
||||
|
||||
void CommandLineInterfaceTest::Run(const string& command) {
|
||||
vector<string> args = Split(command, " ", true);
|
||||
std::vector<string> args = Split(command, " ", true);
|
||||
|
||||
if (!disallow_plugins_) {
|
||||
cli_.AllowPlugins("prefix-");
|
||||
@ -721,7 +721,7 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
|
||||
|
||||
TEST_F(CommandLineInterfaceTest, Win32ErrorMessage) {
|
||||
EXPECT_EQ("The system cannot find the file specified.\r\n",
|
||||
Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
|
||||
Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
|
||||
}
|
||||
|
||||
#endif // defined(_WIN32) || defined(__CYGWIN__)
|
||||
@ -1818,7 +1818,7 @@ class EncodeDecodeTest : public testing::Test {
|
||||
enum ReturnCode { SUCCESS, ERROR };
|
||||
|
||||
bool Run(const string& command) {
|
||||
vector<string> args;
|
||||
std::vector<string> args;
|
||||
args.push_back("protoc");
|
||||
SplitStringUsing(command, " ", &args);
|
||||
args.push_back("--proto_path=" + TestSourceDir());
|
||||
|
@ -114,7 +114,7 @@ class MockGeneratorContext : public GeneratorContext {
|
||||
}
|
||||
|
||||
private:
|
||||
map<string, string*> files_;
|
||||
std::map<string, string*> files_;
|
||||
};
|
||||
|
||||
TEST(BootstrapTest, GeneratedDescriptorMatches) {
|
||||
|
@ -70,7 +70,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
|
||||
EnumGenerator::~EnumGenerator() {}
|
||||
|
||||
void EnumGenerator::FillForwardDeclaration(
|
||||
map<string, const EnumDescriptor*>* enum_names) {
|
||||
std::map<string, const EnumDescriptor*>* enum_names) {
|
||||
if (!options_.proto_h) {
|
||||
return;
|
||||
}
|
||||
@ -78,7 +78,7 @@ void EnumGenerator::FillForwardDeclaration(
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
map<string, string> vars;
|
||||
std::map<string, string> vars;
|
||||
vars["classname"] = classname_;
|
||||
vars["short_name"] = descriptor_->name();
|
||||
vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : "");
|
||||
@ -180,7 +180,7 @@ GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
|
||||
map<string, string> vars;
|
||||
std::map<string, string> vars;
|
||||
vars["nested_name"] = descriptor_->name();
|
||||
vars["classname"] = classname_;
|
||||
vars["constexpr"] = options_.proto_h ? "constexpr " : "";
|
||||
@ -229,33 +229,36 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
|
||||
}
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateDescriptorInitializer(
|
||||
io::Printer* printer, int index) {
|
||||
map<string, string> vars;
|
||||
vars["classname"] = classname_;
|
||||
vars["index"] = SimpleItoa(index);
|
||||
void EnumGenerator::GenerateDescriptorInitializer(io::Printer* printer) {
|
||||
std::map<string, string> vars;
|
||||
vars["index"] = SimpleItoa(descriptor_->index());
|
||||
vars["index_in_metadata"] = SimpleItoa(index_in_metadata_);
|
||||
|
||||
if (descriptor_->containing_type() == NULL) {
|
||||
printer->Print(vars,
|
||||
"$classname$_descriptor_ = file->enum_type($index$);\n");
|
||||
"file_level_enum_descriptors[$index_in_metadata$] = "
|
||||
"file->enum_type($index$);\n");
|
||||
} else {
|
||||
vars["parent"] = ClassName(descriptor_->containing_type(), false);
|
||||
printer->Print(vars,
|
||||
"$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n");
|
||||
"file_level_enum_descriptors[$index_in_metadata$] = "
|
||||
"$parent$_descriptor->enum_type($index$);\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateMethods(io::Printer* printer) {
|
||||
map<string, string> vars;
|
||||
std::map<string, string> vars;
|
||||
vars["classname"] = classname_;
|
||||
vars["index_in_metadata"] = SimpleItoa(index_in_metadata_);
|
||||
vars["constexpr"] = options_.proto_h ? "constexpr " : "";
|
||||
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
printer->Print(vars,
|
||||
"const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
|
||||
" protobuf_AssignDescriptorsOnce();\n"
|
||||
" return $classname$_descriptor_;\n"
|
||||
"}\n");
|
||||
printer->Print(
|
||||
vars,
|
||||
"const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
|
||||
" protobuf_AssignDescriptorsOnce();\n"
|
||||
" return file_level_enum_descriptors[$index_in_metadata$];\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
printer->Print(vars,
|
||||
@ -266,13 +269,13 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
|
||||
// each number once by first constructing a set containing all valid
|
||||
// numbers, then printing a case statement for each element.
|
||||
|
||||
set<int> numbers;
|
||||
std::set<int> numbers;
|
||||
for (int j = 0; j < descriptor_->value_count(); j++) {
|
||||
const EnumValueDescriptor* value = descriptor_->value(j);
|
||||
numbers.insert(value->number());
|
||||
}
|
||||
|
||||
for (set<int>::iterator iter = numbers.begin();
|
||||
for (std::set<int>::iterator iter = numbers.begin();
|
||||
iter != numbers.end(); ++iter) {
|
||||
printer->Print(
|
||||
" case $number$:\n",
|
||||
|
@ -66,7 +66,8 @@ class EnumGenerator {
|
||||
// enums. A given key in enum_names will map from an enum class name to the
|
||||
// EnumDescriptor that was responsible for its inclusion in the map. This can
|
||||
// be used to associate the descriptor with the code generated for it.
|
||||
void FillForwardDeclaration(map<string, const EnumDescriptor*>* enum_names);
|
||||
void FillForwardDeclaration(
|
||||
std::map<string, const EnumDescriptor*>* enum_names);
|
||||
|
||||
// Generate header code defining the enum. This code should be placed
|
||||
// within the enum's package namespace, but NOT within any class, even for
|
||||
@ -87,7 +88,7 @@ class EnumGenerator {
|
||||
|
||||
// Generate code that initializes the global variable storing the enum's
|
||||
// descriptor.
|
||||
void GenerateDescriptorInitializer(io::Printer* printer, int index);
|
||||
void GenerateDescriptorInitializer(io::Printer* printer);
|
||||
|
||||
// Generate non-inline methods related to the enum, such as IsValidValue().
|
||||
// Goes in the .cc file.
|
||||
@ -100,6 +101,9 @@ class EnumGenerator {
|
||||
// whether to generate the *_ARRAYSIZE constant.
|
||||
const bool generate_array_size_;
|
||||
|
||||
int index_in_metadata_;
|
||||
|
||||
friend class FileGenerator;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace cpp {
|
||||
namespace {
|
||||
|
||||
void SetEnumVariables(const FieldDescriptor* descriptor,
|
||||
map<string, string>* variables,
|
||||
std::map<string, string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
|
||||
@ -82,7 +82,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
|
||||
void EnumFieldGenerator::
|
||||
GenerateInlineAccessorDefinitions(io::Printer* printer,
|
||||
bool is_inline) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["inline"] = is_inline ? "inline " : "";
|
||||
printer->Print(variables,
|
||||
"$inline$$type$ $classname$::$name$() const {\n"
|
||||
@ -121,6 +121,11 @@ GenerateConstructorCode(io::Printer* printer) const {
|
||||
printer->Print(variables_, "$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::
|
||||
GenerateCopyConstructorCode(io::Printer* printer) const {
|
||||
printer->Print(variables_, "$name$_ = from.$name$_;\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::
|
||||
GenerateMergeFromCodedStream(io::Printer* printer) const {
|
||||
printer->Print(variables_,
|
||||
@ -186,7 +191,7 @@ EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
|
||||
void EnumOneofFieldGenerator::
|
||||
GenerateInlineAccessorDefinitions(io::Printer* printer,
|
||||
bool is_inline) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["inline"] = is_inline ? "inline " : "";
|
||||
printer->Print(variables,
|
||||
"$inline$$type$ $classname$::$name$() const {\n"
|
||||
@ -223,8 +228,9 @@ GenerateSwappingCode(io::Printer* printer) const {
|
||||
|
||||
void EnumOneofFieldGenerator::
|
||||
GenerateConstructorCode(io::Printer* printer) const {
|
||||
printer->Print(variables_,
|
||||
" $classname$_default_oneof_instance_->$name$_ = $default$;\n");
|
||||
printer->Print(
|
||||
variables_,
|
||||
" $classname$_default_oneof_instance_.$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@ -262,7 +268,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
|
||||
void RepeatedEnumFieldGenerator::
|
||||
GenerateInlineAccessorDefinitions(io::Printer* printer,
|
||||
bool is_inline) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["inline"] = is_inline ? "inline " : "";
|
||||
printer->Print(variables,
|
||||
"$inline$$type$ $classname$::$name$(int index) const {\n"
|
||||
@ -310,11 +316,6 @@ GenerateMergingCode(io::Printer* printer) const {
|
||||
printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::
|
||||
GenerateUnsafeMergingCode(io::Printer* printer) const {
|
||||
printer->Print(variables_, "$name$_.UnsafeMergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::
|
||||
GenerateSwappingCode(io::Printer* printer) const {
|
||||
printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
|
||||
|
@ -58,6 +58,7 @@ class EnumFieldGenerator : public FieldGenerator {
|
||||
void GenerateMergingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
void GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateMergeFromCodedStream(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
@ -65,7 +66,7 @@ class EnumFieldGenerator : public FieldGenerator {
|
||||
|
||||
protected:
|
||||
const FieldDescriptor* descriptor_;
|
||||
map<string, string> variables_;
|
||||
std::map<string, string> variables_;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
|
||||
@ -101,9 +102,9 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
|
||||
bool is_inline) const;
|
||||
void GenerateClearingCode(io::Printer* printer) const;
|
||||
void GenerateMergingCode(io::Printer* printer) const;
|
||||
void GenerateUnsafeMergingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
void GenerateCopyConstructorCode(io::Printer* printer) const {}
|
||||
void GenerateMergeFromCodedStream(io::Printer* printer) const;
|
||||
void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
|
||||
@ -112,7 +113,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
|
||||
|
||||
private:
|
||||
const FieldDescriptor* descriptor_;
|
||||
map<string, string> variables_;
|
||||
std::map<string, string> variables_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
|
||||
};
|
||||
|
@ -92,7 +92,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
|
||||
ExtensionGenerator::~ExtensionGenerator() {}
|
||||
|
||||
void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
|
||||
map<string, string> vars;
|
||||
std::map<string, string> vars;
|
||||
vars["extendee" ] = ExtendeeClassName(descriptor_);
|
||||
vars["number" ] = SimpleItoa(descriptor_->number());
|
||||
vars["type_traits" ] = type_traits_;
|
||||
@ -128,7 +128,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
ClassName(descriptor_->extension_scope(), false) + "::";
|
||||
string name = scope + descriptor_->name();
|
||||
|
||||
map<string, string> vars;
|
||||
std::map<string, string> vars;
|
||||
vars["extendee" ] = ExtendeeClassName(descriptor_);
|
||||
vars["type_traits" ] = type_traits_;
|
||||
vars["name" ] = name;
|
||||
@ -167,7 +167,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
}
|
||||
|
||||
void ExtensionGenerator::GenerateRegistration(io::Printer* printer) {
|
||||
map<string, string> vars;
|
||||
std::map<string, string> vars;
|
||||
vars["extendee" ] = ExtendeeClassName(descriptor_);
|
||||
vars["number" ] = SimpleItoa(descriptor_->number());
|
||||
vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
|
||||
|
@ -59,7 +59,7 @@ namespace cpp {
|
||||
using internal::WireFormat;
|
||||
|
||||
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
|
||||
map<string, string>* variables,
|
||||
std::map<string, string>* variables,
|
||||
const Options& options) {
|
||||
(*variables)["name"] = FieldName(descriptor);
|
||||
(*variables)["index"] = SimpleItoa(descriptor->index());
|
||||
@ -98,7 +98,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
|
||||
}
|
||||
|
||||
void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
|
||||
map<string, string>* variables) {
|
||||
std::map<string, string>* variables) {
|
||||
const string prefix = descriptor->containing_oneof()->name() + "_.";
|
||||
(*variables)["oneof_prefix"] = prefix;
|
||||
(*variables)["oneof_name"] = descriptor->containing_oneof()->name();
|
||||
|
@ -61,11 +61,11 @@ namespace cpp {
|
||||
// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
|
||||
// 'deprecation'].
|
||||
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
|
||||
map<string, string>* variables,
|
||||
std::map<string, string>* variables,
|
||||
const Options& options);
|
||||
|
||||
void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
|
||||
map<string, string>* variables);
|
||||
std::map<string, string>* variables);
|
||||
|
||||
class FieldGenerator {
|
||||
public:
|
||||
@ -124,10 +124,20 @@ class FieldGenerator {
|
||||
io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate lines of code (statements, not declarations) which clear the
|
||||
// field. This is used to define the clear_$name$() method as well as
|
||||
// the Clear() method for the whole message.
|
||||
// field. This is used to define the clear_$name$() method
|
||||
virtual void GenerateClearingCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate lines of code (statements, not declarations) which clear the field
|
||||
// as part of the Clear() method for the whole message. For message types
|
||||
// which have field presence bits, MessageGenerator::GenerateClear will have
|
||||
// already checked the presence bits.
|
||||
//
|
||||
// Since most field types can re-use GenerateClearingCode, this method is not
|
||||
// pure virtual.
|
||||
virtual void GenerateMessageClearingCode(io::Printer* printer) const {
|
||||
GenerateClearingCode(printer);
|
||||
}
|
||||
|
||||
// Generate lines of code (statements, not declarations) which merges the
|
||||
// contents of the field from the current message to the target message,
|
||||
// which is stored in the generated code variable "from".
|
||||
@ -136,12 +146,8 @@ class FieldGenerator {
|
||||
// GenerateMergeFrom method.
|
||||
virtual void GenerateMergingCode(io::Printer* printer) const = 0;
|
||||
|
||||
// The same, but the generated code may or may not check the possibility that
|
||||
// the two objects being merged have the same address. To be safe, callers
|
||||
// should avoid calling this unless they know the objects are different.
|
||||
virtual void GenerateUnsafeMergingCode(io::Printer* printer) const {
|
||||
GenerateMergingCode(printer);
|
||||
}
|
||||
// Generates a copy constructor
|
||||
virtual void GenerateCopyConstructorCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate lines of code (statements, not declarations) which swaps
|
||||
// this field and the corresponding field of another message, which
|
||||
|
@ -60,33 +60,42 @@ namespace cpp {
|
||||
FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
|
||||
: file_(file),
|
||||
options_(options),
|
||||
message_generators_(
|
||||
new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
|
||||
enum_generators_(
|
||||
new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]),
|
||||
service_generators_(
|
||||
new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
|
||||
extension_generators_(
|
||||
new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) {
|
||||
message_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<MessageGenerator>[ file->message_type_count() ]),
|
||||
enum_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<EnumGenerator>[ file->enum_type_count() ]),
|
||||
service_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<ServiceGenerator>[ file->service_count() ]),
|
||||
extension_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<ExtensionGenerator>[ file->extension_count() ]) {
|
||||
|
||||
for (int i = 0; i < file->message_type_count(); i++) {
|
||||
message_generators_[i].reset(
|
||||
new MessageGenerator(file->message_type(i), options));
|
||||
message_generators_owner_[i].reset(
|
||||
new MessageGenerator(file->message_type(i), options));
|
||||
message_generators_owner_[i]->Flatten(&message_generators_);
|
||||
}
|
||||
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->AddGenerators(&enum_generators_,
|
||||
&extension_generators_);
|
||||
}
|
||||
|
||||
for (int i = 0; i < file->enum_type_count(); i++) {
|
||||
enum_generators_[i].reset(
|
||||
new EnumGenerator(file->enum_type(i), options));
|
||||
enum_generators_owner_[i].reset(
|
||||
new EnumGenerator(file->enum_type(i), options));
|
||||
enum_generators_.push_back(enum_generators_owner_[i].get());
|
||||
}
|
||||
|
||||
for (int i = 0; i < file->service_count(); i++) {
|
||||
service_generators_[i].reset(
|
||||
new ServiceGenerator(file->service(i), options));
|
||||
service_generators_owner_[i].reset(
|
||||
new ServiceGenerator(file->service(i), options));
|
||||
service_generators_.push_back(service_generators_owner_[i].get());
|
||||
}
|
||||
|
||||
for (int i = 0; i < file->extension_count(); i++) {
|
||||
extension_generators_[i].reset(
|
||||
new ExtensionGenerator(file->extension(i), options));
|
||||
extension_generators_owner_[i].reset(
|
||||
new ExtensionGenerator(file->extension(i), options));
|
||||
extension_generators_.push_back(extension_generators_owner_[i].get());
|
||||
}
|
||||
|
||||
package_parts_ = Split(file_->package(), ".", true);
|
||||
@ -94,29 +103,7 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
|
||||
|
||||
FileGenerator::~FileGenerator() {}
|
||||
|
||||
void FileGenerator::GenerateProtoHeader(io::Printer* printer,
|
||||
const string& info_path) {
|
||||
if (!options_.proto_h) {
|
||||
return;
|
||||
}
|
||||
|
||||
string filename_identifier = FilenameIdentifier(file_->name());
|
||||
GenerateTopHeaderGuard(printer, filename_identifier);
|
||||
|
||||
|
||||
GenerateLibraryIncludes(printer);
|
||||
|
||||
for (int i = 0; i < file_->public_dependency_count(); i++) {
|
||||
const FileDescriptor* dep = file_->public_dependency(i);
|
||||
const char* extension = ".proto.h";
|
||||
string dependency = StripProto(dep->name()) + extension;
|
||||
printer->Print(
|
||||
"#include \"$dependency$\" // IWYU pragma: export\n",
|
||||
"dependency", dependency);
|
||||
}
|
||||
|
||||
GenerateMetadataPragma(printer, info_path);
|
||||
|
||||
void FileGenerator::GenerateHeader(io::Printer* printer) {
|
||||
printer->Print(
|
||||
"// @@protoc_insertion_point(includes)\n");
|
||||
|
||||
@ -166,6 +153,32 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer,
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(global_scope)\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateProtoHeader(io::Printer* printer,
|
||||
const string& info_path) {
|
||||
if (!options_.proto_h) {
|
||||
return;
|
||||
}
|
||||
|
||||
string filename_identifier = FilenameIdentifier(file_->name());
|
||||
GenerateTopHeaderGuard(printer, filename_identifier);
|
||||
|
||||
|
||||
GenerateLibraryIncludes(printer);
|
||||
|
||||
for (int i = 0; i < file_->public_dependency_count(); i++) {
|
||||
const FileDescriptor* dep = file_->public_dependency(i);
|
||||
const char* extension = ".proto.h";
|
||||
string dependency = StripProto(dep->name()) + extension;
|
||||
printer->Print(
|
||||
"#include \"$dependency$\" // IWYU pragma: export\n",
|
||||
"dependency", dependency);
|
||||
}
|
||||
|
||||
GenerateMetadataPragma(printer, info_path);
|
||||
|
||||
GenerateHeader(printer);
|
||||
|
||||
GenerateBottomHeaderGuard(printer, filename_identifier);
|
||||
}
|
||||
@ -185,59 +198,29 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer,
|
||||
GenerateDependencyIncludes(printer);
|
||||
GenerateMetadataPragma(printer, info_path);
|
||||
|
||||
printer->Print(
|
||||
"// @@protoc_insertion_point(includes)\n");
|
||||
|
||||
|
||||
|
||||
// Open namespace.
|
||||
GenerateNamespaceOpeners(printer);
|
||||
|
||||
if (!options_.proto_h) {
|
||||
GenerateGlobalStateFunctionDeclarations(printer);
|
||||
GenerateMessageForwardDeclarations(printer);
|
||||
GenerateHeader(printer);
|
||||
} else {
|
||||
// This is unfortunately necessary for some plugins. I don't see why we
|
||||
// need two of the same insertion points.
|
||||
// TODO(gerbens) remove this.
|
||||
printer->Print(
|
||||
"// @@protoc_insertion_point(includes)\n");
|
||||
|
||||
printer->Print("\n");
|
||||
// Open namespace.
|
||||
GenerateNamespaceOpeners(printer);
|
||||
printer->Print(
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(namespace_scope)\n");
|
||||
// Close up namespace.
|
||||
GenerateNamespaceClosers(printer);
|
||||
|
||||
GenerateEnumDefinitions(printer);
|
||||
|
||||
printer->Print(kThickSeparator);
|
||||
printer->Print("\n");
|
||||
|
||||
GenerateMessageDefinitions(printer);
|
||||
|
||||
printer->Print("\n");
|
||||
printer->Print(kThickSeparator);
|
||||
printer->Print("\n");
|
||||
|
||||
GenerateServiceDefinitions(printer);
|
||||
|
||||
GenerateExtensionIdentifiers(printer);
|
||||
|
||||
printer->Print("\n");
|
||||
printer->Print(kThickSeparator);
|
||||
printer->Print("\n");
|
||||
|
||||
GenerateInlineFunctionDefinitions(printer);
|
||||
printer->Print(
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(global_scope)\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(namespace_scope)\n");
|
||||
|
||||
// Close up namespace.
|
||||
GenerateNamespaceClosers(printer);
|
||||
|
||||
if (!options_.proto_h) {
|
||||
// We need to specialize some templates in the ::google::protobuf namespace:
|
||||
GenerateProto2NamespaceEnumSpecializations(printer);
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(global_scope)\n"
|
||||
"\n");
|
||||
|
||||
GenerateBottomHeaderGuard(printer, filename_identifier);
|
||||
}
|
||||
|
||||
@ -267,7 +250,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
"right", use_system_include ? ">" : "\"");
|
||||
|
||||
// Unknown fields implementation in lite mode uses StringOutputStream
|
||||
if (!UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) {
|
||||
if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
|
||||
printer->Print(
|
||||
"#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
|
||||
}
|
||||
@ -297,25 +280,48 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
|
||||
GenerateNamespaceOpeners(printer);
|
||||
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (IsMapEntryMessage(message_generators_[i]->descriptor_)) continue;
|
||||
printer->Print(
|
||||
"class $classname$DefaultTypeInternal : "
|
||||
"public ::google::protobuf::internal::ExplicitlyConstructed<$classname$> {};\n"
|
||||
"$classname$DefaultTypeInternal _$classname$_default_instance_;\n",
|
||||
"classname", message_generators_[i]->classname_);
|
||||
}
|
||||
|
||||
if (HasDescriptorMethods(file_, options_)) {
|
||||
printer->Print(
|
||||
"\n"
|
||||
"namespace {\n"
|
||||
"\n");
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
message_generators_[i]->GenerateDescriptorDeclarations(printer);
|
||||
|
||||
if (!message_generators_.empty()) {
|
||||
printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n",
|
||||
"size", SimpleItoa(message_generators_.size()));
|
||||
}
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
if (!enum_generators_.empty()) {
|
||||
printer->Print(
|
||||
"const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
|
||||
"name", ClassName(file_->enum_type(i), false));
|
||||
"const ::google::protobuf::EnumDescriptor* "
|
||||
"file_level_enum_descriptors[$size$];\n",
|
||||
"size", SimpleItoa(enum_generators_.size()));
|
||||
}
|
||||
if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
|
||||
printer->Print(
|
||||
"const ::google::protobuf::ServiceDescriptor* "
|
||||
"file_level_service_descriptors[$size$];\n",
|
||||
"size", SimpleItoa(file_->service_count()));
|
||||
}
|
||||
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->index_in_metadata_ = i;
|
||||
message_generators_[i]->GenerateDescriptorDeclarations(printer);
|
||||
}
|
||||
for (int i = 0; i < enum_generators_.size(); i++) {
|
||||
enum_generators_[i]->index_in_metadata_ = i;
|
||||
}
|
||||
if (HasGenericServices(file_, options_)) {
|
||||
for (int i = 0; i < file_->service_count(); i++) {
|
||||
printer->Print(
|
||||
"const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
|
||||
"name", file_->service(i)->name());
|
||||
for (int i = 0; i < service_generators_.size(); i++) {
|
||||
service_generators_[i]->index_in_metadata_ = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,26 +336,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
GenerateBuildDescriptors(printer);
|
||||
|
||||
// Generate enums.
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
for (int i = 0; i < enum_generators_.size(); i++) {
|
||||
enum_generators_[i]->GenerateMethods(printer);
|
||||
}
|
||||
|
||||
// Generate classes.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
if (i == 0 && HasGeneratedMethods(file_, options_)) {
|
||||
printer->Print(
|
||||
"\n"
|
||||
"namespace {\n"
|
||||
"\n"
|
||||
"static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD"
|
||||
" GOOGLE_ATTRIBUTE_NORETURN;\n"
|
||||
"static void MergeFromFail(int line) {\n"
|
||||
" ::google::protobuf::internal::MergeFromFail(__FILE__, line);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"} // namespace\n"
|
||||
"\n");
|
||||
}
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
printer->Print("\n");
|
||||
printer->Print(kThickSeparator);
|
||||
printer->Print("\n");
|
||||
@ -364,7 +356,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
|
||||
if (HasGenericServices(file_, options_)) {
|
||||
// Generate services.
|
||||
for (int i = 0; i < file_->service_count(); i++) {
|
||||
for (int i = 0; i < service_generators_.size(); i++) {
|
||||
if (i == 0) printer->Print("\n");
|
||||
printer->Print(kThickSeparator);
|
||||
printer->Print("\n");
|
||||
@ -373,7 +365,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
}
|
||||
|
||||
// Define extensions.
|
||||
for (int i = 0; i < file_->extension_count(); i++) {
|
||||
for (int i = 0; i < extension_generators_.size(); i++) {
|
||||
extension_generators_[i]->GenerateDefinition(printer);
|
||||
}
|
||||
|
||||
@ -391,8 +383,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
class FileGenerator::ForwardDeclarations {
|
||||
public:
|
||||
~ForwardDeclarations() {
|
||||
for (map<string, ForwardDeclarations *>::iterator it = namespaces_.begin(),
|
||||
end = namespaces_.end();
|
||||
for (std::map<string, ForwardDeclarations*>::iterator
|
||||
it = namespaces_.begin(),
|
||||
end = namespaces_.end();
|
||||
it != end; ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
@ -407,11 +400,11 @@ class FileGenerator::ForwardDeclarations {
|
||||
return ns;
|
||||
}
|
||||
|
||||
map<string, const Descriptor*>& classes() { return classes_; }
|
||||
map<string, const EnumDescriptor*>& enums() { return enums_; }
|
||||
std::map<string, const Descriptor*>& classes() { return classes_; }
|
||||
std::map<string, const EnumDescriptor*>& enums() { return enums_; }
|
||||
|
||||
void Print(io::Printer* printer) const {
|
||||
for (map<string, const EnumDescriptor *>::const_iterator
|
||||
for (std::map<string, const EnumDescriptor *>::const_iterator
|
||||
it = enums_.begin(),
|
||||
end = enums_.end();
|
||||
it != end; ++it) {
|
||||
@ -420,13 +413,21 @@ class FileGenerator::ForwardDeclarations {
|
||||
printer->Print("bool $enumname$_IsValid(int value);\n", "enumname",
|
||||
it->first);
|
||||
}
|
||||
for (map<string, const Descriptor *>::const_iterator it = classes_.begin(),
|
||||
end = classes_.end();
|
||||
for (std::map<string, const Descriptor*>::const_iterator
|
||||
it = classes_.begin(),
|
||||
end = classes_.end();
|
||||
it != end; ++it) {
|
||||
printer->Print("class $classname$;\n", "classname", it->first);
|
||||
printer->Annotate("classname", it->second);
|
||||
|
||||
printer->Print(
|
||||
"class $classname$DefaultTypeInternal;\n"
|
||||
"extern $classname$DefaultTypeInternal "
|
||||
"_$classname$_default_instance_;\n", // NOLINT
|
||||
"classname",
|
||||
it->first);
|
||||
}
|
||||
for (map<string, ForwardDeclarations *>::const_iterator
|
||||
for (std::map<string, ForwardDeclarations *>::const_iterator
|
||||
it = namespaces_.begin(),
|
||||
end = namespaces_.end();
|
||||
it != end; ++it) {
|
||||
@ -440,9 +441,9 @@ class FileGenerator::ForwardDeclarations {
|
||||
|
||||
|
||||
private:
|
||||
map<string, ForwardDeclarations*> namespaces_;
|
||||
map<string, const Descriptor*> classes_;
|
||||
map<string, const EnumDescriptor*> enums_;
|
||||
std::map<string, ForwardDeclarations*> namespaces_;
|
||||
std::map<string, const Descriptor*> classes_;
|
||||
std::map<string, const EnumDescriptor*> enums_;
|
||||
};
|
||||
|
||||
void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
@ -465,75 +466,135 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
// and we only use AddDescriptors() to allocate default instances.
|
||||
|
||||
if (HasDescriptorMethods(file_, options_)) {
|
||||
printer->Print(
|
||||
"\n"
|
||||
"void $assigndescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
|
||||
"void $assigndescriptorsname$() {\n",
|
||||
"assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
|
||||
printer->Indent();
|
||||
if (!message_generators_.empty()) {
|
||||
printer->Print(
|
||||
"\n"
|
||||
"const ::google::protobuf::uint32* $offsetfunname$() GOOGLE_ATTRIBUTE_COLD;\n"
|
||||
"const ::google::protobuf::uint32* $offsetfunname$() {\n",
|
||||
"offsetfunname", GlobalOffsetTableName(file_->name()));
|
||||
printer->Indent();
|
||||
|
||||
// Make sure the file has found its way into the pool. If a descriptor
|
||||
// is requested *during* static init then AddDescriptors() may not have
|
||||
// been called yet, so we call it manually. Note that it's fine if
|
||||
// AddDescriptors() is called multiple times.
|
||||
printer->Print(
|
||||
"$adddescriptorsname$();\n",
|
||||
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
|
||||
|
||||
// Get the file's descriptor from the pool.
|
||||
printer->Print(
|
||||
"const ::google::protobuf::FileDescriptor* file =\n"
|
||||
" ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
|
||||
" \"$filename$\");\n"
|
||||
// Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
|
||||
// being unused when compiling an empty .proto file.
|
||||
"GOOGLE_CHECK(file != NULL);\n",
|
||||
"filename", file_->name());
|
||||
|
||||
// Go through all the stuff defined in this file and generated code to
|
||||
// assign the global descriptor pointers based on the file descriptor.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
message_generators_[i]->GenerateDescriptorInitializer(printer, i);
|
||||
}
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
|
||||
}
|
||||
if (HasGenericServices(file_, options_)) {
|
||||
for (int i = 0; i < file_->service_count(); i++) {
|
||||
service_generators_[i]->GenerateDescriptorInitializer(printer, i);
|
||||
printer->Print("static const ::google::protobuf::uint32 offsets[] = {\n");
|
||||
printer->Indent();
|
||||
std::vector<std::pair<size_t, size_t> > pairs;
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
pairs.push_back(message_generators_[i]->GenerateOffsets(printer));
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
" };\n"
|
||||
" return offsets;\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"}\n"
|
||||
"\n");
|
||||
printer->Print(
|
||||
"static const ::google::protobuf::internal::MigrationSchema schemas[] = {\n");
|
||||
printer->Indent();
|
||||
{
|
||||
int offset = 0;
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->GenerateSchema(printer, offset,
|
||||
pairs[i].second);
|
||||
offset += pairs[i].first;
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n"
|
||||
"\n"
|
||||
"static const ::google::protobuf::internal::DefaultInstanceData "
|
||||
"file_default_instances[] = {\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
const Descriptor* descriptor = message_generators_[i]->descriptor_;
|
||||
if (IsMapEntryMessage(descriptor)) continue;
|
||||
|
||||
string oneof_default = "NULL";
|
||||
if (message_generators_[i]->descriptor_->oneof_decl_count()) {
|
||||
oneof_default =
|
||||
"&" + ClassName(descriptor, false) + "_default_oneof_instance_";
|
||||
}
|
||||
printer->Print(
|
||||
"{reinterpret_cast<const "
|
||||
"::google::protobuf::Message*>(&_$classname$_default_instance_), "
|
||||
"$oneof_default$},\n",
|
||||
"classname", ClassName(descriptor, false), "oneof_default",
|
||||
oneof_default);
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n"
|
||||
"\n");
|
||||
} else {
|
||||
// we still need these symbols to exist
|
||||
printer->Print(
|
||||
"inline ::google::protobuf::uint32* $offsetfunname$() { return NULL; }\n"
|
||||
"static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n"
|
||||
"static const ::google::protobuf::internal::DefaultInstanceData* "
|
||||
"file_default_instances = NULL;\n",
|
||||
"offsetfunname",
|
||||
GlobalOffsetTableName(file_->name()));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// protobuf_AssignDescriptorsOnce(): The first time it is called, calls
|
||||
// AssignDescriptors(). All later times, waits for the first call to
|
||||
// complete and then returns.
|
||||
string message_factory = "NULL";
|
||||
printer->Print(
|
||||
"namespace {\n"
|
||||
"\n"
|
||||
"GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
|
||||
"void protobuf_AssignDescriptors() {\n"
|
||||
// Make sure the file has found its way into the pool. If a descriptor
|
||||
// is requested *during* static init then AddDescriptors() may not have
|
||||
// been called yet, so we call it manually. Note that it's fine if
|
||||
// AddDescriptors() is called multiple times.
|
||||
" $adddescriptorsname$();\n"
|
||||
" ::google::protobuf::MessageFactory* factory = $factory$;\n"
|
||||
" AssignDescriptors(\n"
|
||||
" \"$filename$\", schemas, file_default_instances, "
|
||||
"$offsetfunname$(), factory,\n"
|
||||
" $metadata$, $enum_descriptors$, $service_descriptors$);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void protobuf_AssignDescriptorsOnce() {\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
|
||||
" &$assigndescriptorsname$);\n"
|
||||
" static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
"assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
|
||||
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
|
||||
"offsetfunname", GlobalOffsetTableName(file_->name()), "filename",
|
||||
file_->name(), "metadata",
|
||||
!message_generators_.empty() ? "file_level_metadata" : "NULL",
|
||||
"enum_descriptors",
|
||||
!enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
|
||||
"service_descriptors",
|
||||
HasGenericServices(file_, options_) && file_->service_count() > 0
|
||||
? "file_level_service_descriptors"
|
||||
: "NULL",
|
||||
"factory", message_factory);
|
||||
|
||||
// protobuf_RegisterTypes(): Calls
|
||||
// MessageFactory::InternalRegisterGeneratedType() for each message type.
|
||||
// Only here because of useless string reference that we don't want in
|
||||
// protobuf_AssignDescriptorsOnce, because that is called from all the
|
||||
// GetMetadata member methods.
|
||||
printer->Print(
|
||||
"void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;\n"
|
||||
"void protobuf_RegisterTypes(const ::std::string&) {\n"
|
||||
" protobuf_AssignDescriptorsOnce();\n");
|
||||
printer->Indent();
|
||||
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
// All normal messages can be done generically
|
||||
if (!message_generators_.empty()) {
|
||||
printer->Print(
|
||||
"::google::protobuf::internal::RegisterAllTypes(file_level_metadata, $size$);\n",
|
||||
"size", SimpleItoa(message_generators_.size()));
|
||||
}
|
||||
|
||||
// Map types are treated special
|
||||
// TODO(gerbens) find a way to treat maps more like normal messages.
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->GenerateTypeRegistrations(printer);
|
||||
}
|
||||
|
||||
@ -553,7 +614,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
"shutdownfilename", GlobalShutdownFileName(file_->name()));
|
||||
printer->Indent();
|
||||
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->GenerateShutdownCode(printer);
|
||||
}
|
||||
|
||||
@ -566,8 +627,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
// Now generate the InitDefaults() function.
|
||||
printer->Print(
|
||||
"void $initdefaultsname$_impl() {\n"
|
||||
" GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
|
||||
"\n",
|
||||
" GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n"
|
||||
"",
|
||||
// Vars.
|
||||
"initdefaultsname", GlobalInitDefaultsName(file_->name()));
|
||||
|
||||
@ -586,26 +647,28 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
"name", add_desc_name);
|
||||
}
|
||||
|
||||
// Force initialization of primitive values we depend on.
|
||||
printer->Print("::google::protobuf::internal::InitProtobufDefaults();\n");
|
||||
|
||||
// Allocate and initialize default instances. This can't be done lazily
|
||||
// since default instances are returned by simple accessors and are used with
|
||||
// extensions. Speaking of which, we also register extensions at this time.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
|
||||
}
|
||||
for (int i = 0; i < file_->extension_count(); i++) {
|
||||
for (int i = 0; i < extension_generators_.size(); i++) {
|
||||
extension_generators_[i]->GenerateRegistration(printer);
|
||||
}
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"}\n"
|
||||
"\n"
|
||||
"GOOGLE_PROTOBUF_DECLARE_ONCE($initdefaultsname$_once_);\n"
|
||||
"void $initdefaultsname$() {\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&$initdefaultsname$_once_,\n"
|
||||
" &$initdefaultsname$_impl);\n"
|
||||
" static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&once, &$initdefaultsname$_impl);\n"
|
||||
"}\n",
|
||||
"initdefaultsname", GlobalInitDefaultsName(file_->name()));
|
||||
|
||||
@ -614,8 +677,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
// Now generate the AddDescriptors() function.
|
||||
printer->Print(
|
||||
"void $adddescriptorsname$_impl() {\n"
|
||||
" GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
|
||||
"\n"
|
||||
" $initdefaultsname$();\n",
|
||||
// Vars.
|
||||
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
|
||||
@ -632,60 +693,42 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
|
||||
string file_data;
|
||||
file_proto.SerializeToString(&file_data);
|
||||
|
||||
printer->Print("static const char descriptor[] = {\n");
|
||||
printer->Indent();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
bool breakdown_large_file = true;
|
||||
#else
|
||||
bool breakdown_large_file = false;
|
||||
#endif
|
||||
// Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
|
||||
// bytes in length". Declare a static array of characters rather than use a
|
||||
// string literal.
|
||||
if (breakdown_large_file && file_data.size() > 65535) {
|
||||
// This has to be explicitly marked as a signed char because the generated
|
||||
// code puts negative values in the array, and sometimes plain char is
|
||||
// unsigned. That implicit narrowing conversion is not allowed in C++11.
|
||||
// <http://stackoverflow.com/questions/4434140/narrowing-conversions-in-c0x-is-it-just-me-or-does-this-sound-like-a-breakin>
|
||||
// has details on why.
|
||||
printer->Print(
|
||||
"static const signed char descriptor[] = {\n");
|
||||
printer->Indent();
|
||||
|
||||
// Only write 25 bytes per line.
|
||||
if (breakdown_large_file && file_data.size() > 66538) {
|
||||
// Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
|
||||
// bytes in length". Declare a static array of characters rather than use
|
||||
// a string literal. Only write 25 bytes per line.
|
||||
static const int kBytesPerLine = 25;
|
||||
for (int i = 0; i < file_data.size();) {
|
||||
for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
|
||||
printer->Print(
|
||||
"$char$, ",
|
||||
"char", SimpleItoa(file_data[i]));
|
||||
}
|
||||
printer->Print(
|
||||
"\n");
|
||||
for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
|
||||
printer->Print("'$char$', ", "char",
|
||||
CEscape(file_data.substr(i, 1)));
|
||||
}
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n");
|
||||
|
||||
printer->Print(
|
||||
"::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
|
||||
"size", SimpleItoa(file_data.size()));
|
||||
|
||||
} else {
|
||||
printer->Print(
|
||||
"::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
|
||||
|
||||
// Only write 40 bytes per line.
|
||||
static const int kBytesPerLine = 40;
|
||||
for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
|
||||
printer->Print("\n \"$data$\"",
|
||||
"data",
|
||||
EscapeTrigraphs(
|
||||
CEscape(file_data.substr(i, kBytesPerLine))));
|
||||
printer->Print(" \"$data$\"\n", "data",
|
||||
EscapeTrigraphs(CEscape(
|
||||
file_data.substr(i, kBytesPerLine))));
|
||||
}
|
||||
}
|
||||
|
||||
printer->Outdent();
|
||||
printer->Print("};\n");
|
||||
printer->Print(
|
||||
", $size$);\n",
|
||||
"::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n"
|
||||
" descriptor, $size$);\n",
|
||||
"size", SimpleItoa(file_data.size()));
|
||||
}
|
||||
|
||||
// Call MessageFactory::InternalRegisterGeneratedFile().
|
||||
printer->Print(
|
||||
@ -777,14 +820,11 @@ void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
|
||||
decls = decls->AddOrGetNamespace(package_parts_[i]);
|
||||
}
|
||||
// Generate enum definitions.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
message_generators_[i]->FillEnumForwardDeclarations(&decls->enums());
|
||||
}
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
for (int i = 0; i < enum_generators_.size(); i++) {
|
||||
enum_generators_[i]->FillForwardDeclaration(&decls->enums());
|
||||
}
|
||||
// Generate forward declarations of classes.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
message_generators_[i]->FillMessageForwardDeclarations(
|
||||
&decls->classes());
|
||||
}
|
||||
@ -840,12 +880,10 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
|
||||
printer->Print(
|
||||
"#include <google/protobuf/arena.h>\n"
|
||||
"#include <google/protobuf/arenastring.h>\n"
|
||||
"#include <google/protobuf/generated_message_util.h>\n");
|
||||
if (UseUnknownFieldSet(file_, options_)) {
|
||||
printer->Print(
|
||||
"#include <google/protobuf/metadata.h>\n");
|
||||
}
|
||||
if (file_->message_type_count() > 0) {
|
||||
"#include <google/protobuf/generated_message_util.h>\n"
|
||||
"#include <google/protobuf/metadata.h>\n");
|
||||
|
||||
if (!message_generators_.empty()) {
|
||||
if (HasDescriptorMethods(file_, options_)) {
|
||||
printer->Print(
|
||||
"#include <google/protobuf/message.h>\n");
|
||||
@ -855,8 +893,10 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
|
||||
}
|
||||
}
|
||||
printer->Print(
|
||||
"#include <google/protobuf/repeated_field.h>\n"
|
||||
"#include <google/protobuf/extension_set.h>\n");
|
||||
"#include <google/protobuf/repeated_field.h>"
|
||||
" // IWYU pragma: export\n"
|
||||
"#include <google/protobuf/extension_set.h>"
|
||||
" // IWYU pragma: export\n");
|
||||
if (HasMapFields(file_)) {
|
||||
printer->Print(
|
||||
"#include <google/protobuf/map.h>\n");
|
||||
@ -884,7 +924,7 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
|
||||
"#include <google/protobuf/service.h>\n");
|
||||
}
|
||||
|
||||
if (UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) {
|
||||
if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
|
||||
printer->Print(
|
||||
"#include <google/protobuf/unknown_field_set.h>\n");
|
||||
}
|
||||
@ -910,7 +950,7 @@ void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
|
||||
set<string> public_import_names;
|
||||
std::set<string> public_import_names;
|
||||
for (int i = 0; i < file_->public_dependency_count(); i++) {
|
||||
public_import_names.insert(file_->public_dependency(i)->name());
|
||||
}
|
||||
@ -943,33 +983,11 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
|
||||
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
|
||||
"dllexport_decl",
|
||||
options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
|
||||
|
||||
printer->Print(
|
||||
// Note that we don't put dllexport_decl on these because they are only
|
||||
// called by the .pb.cc file in which they are defined.
|
||||
"void $assigndescriptorsname$();\n"
|
||||
"void $shutdownfilename$();\n"
|
||||
"\n",
|
||||
"assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
|
||||
"shutdownfilename", GlobalShutdownFileName(file_->name()));
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) {
|
||||
map<string, const Descriptor*> classes;
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
message_generators_[i]->FillMessageForwardDeclarations(&classes);
|
||||
}
|
||||
for (map<string, const Descriptor *>::const_iterator it = classes.begin(),
|
||||
end = classes.end();
|
||||
it != end; ++it) {
|
||||
printer->Print("class $classname$;\n", "classname", it->first);
|
||||
printer->Annotate("classname", it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
|
||||
// Generate class definitions.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (i > 0) {
|
||||
printer->Print("\n");
|
||||
printer->Print(kThinSeparator);
|
||||
@ -981,10 +999,7 @@ void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
|
||||
|
||||
void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
|
||||
// Generate enum definitions.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
message_generators_[i]->GenerateEnumDefinitions(printer);
|
||||
}
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
for (int i = 0; i < enum_generators_.size(); i++) {
|
||||
enum_generators_[i]->GenerateDefinition(printer);
|
||||
}
|
||||
}
|
||||
@ -992,7 +1007,7 @@ void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
|
||||
void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
|
||||
if (HasGenericServices(file_, options_)) {
|
||||
// Generate service definitions.
|
||||
for (int i = 0; i < file_->service_count(); i++) {
|
||||
for (int i = 0; i < service_generators_.size(); i++) {
|
||||
if (i > 0) {
|
||||
printer->Print("\n");
|
||||
printer->Print(kThinSeparator);
|
||||
@ -1008,9 +1023,10 @@ void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) {
|
||||
// Declare extension identifiers.
|
||||
// Declare extension identifiers. These are in global scope and so only
|
||||
// the global scope extensions.
|
||||
for (int i = 0; i < file_->extension_count(); i++) {
|
||||
extension_generators_[i]->GenerateDeclaration(printer);
|
||||
extension_generators_owner_[i]->GenerateDeclaration(printer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1051,7 +1067,7 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
|
||||
|
||||
printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n");
|
||||
// Generate class inline methods.
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (i > 0) {
|
||||
printer->Print(kThinSeparator);
|
||||
printer->Print("\n");
|
||||
@ -1061,7 +1077,7 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
|
||||
}
|
||||
printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n");
|
||||
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (i > 0) {
|
||||
printer->Print(kThinSeparator);
|
||||
printer->Print("\n");
|
||||
@ -1084,10 +1100,7 @@ void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
|
||||
"#ifndef SWIG\n"
|
||||
"namespace google {\nnamespace protobuf {\n"
|
||||
"\n");
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
|
||||
}
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
for (int i = 0; i < enum_generators_.size(); i++) {
|
||||
enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
|
||||
}
|
||||
printer->Print(
|
||||
|
@ -68,6 +68,9 @@ class FileGenerator {
|
||||
FileGenerator(const FileDescriptor* file, const Options& options);
|
||||
~FileGenerator();
|
||||
|
||||
// Shared code between the two header generators below.
|
||||
void GenerateHeader(io::Printer* printer);
|
||||
|
||||
// info_path, if non-empty, should be the path (relative to printer's output)
|
||||
// to the metadata file describing this proto header.
|
||||
void GenerateProtoHeader(io::Printer* printer,
|
||||
@ -117,18 +120,6 @@ class FileGenerator {
|
||||
// Generates types for classes.
|
||||
void GenerateMessageDefinitions(io::Printer* printer);
|
||||
|
||||
// Generates forward-declarations for just this file's classes. This is
|
||||
// used for .pb.h headers, but not in proto_h mode.
|
||||
void GenerateMessageForwardDeclarations(io::Printer* printer);
|
||||
|
||||
// Fills in types for forward declarations. This is used internally, and
|
||||
// also by other FileGenerators to determine imports' declarations.
|
||||
void FillMessageForwardDeclarations(ForwardDeclarations* decls);
|
||||
void FillMessageDefinitions(ForwardDeclarations* decls);
|
||||
|
||||
// Generates enum definitions.
|
||||
void GenerateEnumForwardDeclarations(io::Printer* printer);
|
||||
void FillEnumForwardDeclarations(ForwardDeclarations* decls);
|
||||
void GenerateEnumDefinitions(io::Printer* printer);
|
||||
|
||||
// Generates generic service definitions.
|
||||
@ -145,13 +136,25 @@ class FileGenerator {
|
||||
const FileDescriptor* file_;
|
||||
const Options options_;
|
||||
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > message_generators_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ServiceGenerator> > service_generators_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_;
|
||||
// Contains the post-order walk of all the messages (and child messages) in
|
||||
// this file. If you need a pre-order walk just reverse iterate.
|
||||
std::vector<MessageGenerator*> message_generators_;
|
||||
std::vector<EnumGenerator*> enum_generators_;
|
||||
std::vector<ServiceGenerator*> service_generators_;
|
||||
std::vector<ExtensionGenerator*> extension_generators_;
|
||||
|
||||
// These members are just for owning (and thus proper deleting). Some of the
|
||||
// message_ and enum_generators above are owned by child messages.
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> >
|
||||
message_generators_owner_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_owner_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ServiceGenerator> >
|
||||
service_generators_owner_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> >
|
||||
extension_generators_owner_;
|
||||
|
||||
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
|
||||
vector<string> package_parts_;
|
||||
std::vector<string> package_parts_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
const string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
string* error) const {
|
||||
vector<pair<string, string> > options;
|
||||
std::vector<std::pair<string, string> > options;
|
||||
ParseGeneratorParameter(parameter, &options);
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
@ -371,9 +371,9 @@ string DefaultValue(const FieldDescriptor* field) {
|
||||
return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
|
||||
case FieldDescriptor::CPPTYPE_DOUBLE: {
|
||||
double value = field->default_value_double();
|
||||
if (value == numeric_limits<double>::infinity()) {
|
||||
if (value == std::numeric_limits<double>::infinity()) {
|
||||
return "::google::protobuf::internal::Infinity()";
|
||||
} else if (value == -numeric_limits<double>::infinity()) {
|
||||
} else if (value == -std::numeric_limits<double>::infinity()) {
|
||||
return "-::google::protobuf::internal::Infinity()";
|
||||
} else if (value != value) {
|
||||
return "::google::protobuf::internal::NaN()";
|
||||
@ -384,9 +384,9 @@ string DefaultValue(const FieldDescriptor* field) {
|
||||
case FieldDescriptor::CPPTYPE_FLOAT:
|
||||
{
|
||||
float value = field->default_value_float();
|
||||
if (value == numeric_limits<float>::infinity()) {
|
||||
if (value == std::numeric_limits<float>::infinity()) {
|
||||
return "static_cast<float>(::google::protobuf::internal::Infinity())";
|
||||
} else if (value == -numeric_limits<float>::infinity()) {
|
||||
} else if (value == -std::numeric_limits<float>::infinity()) {
|
||||
return "static_cast<float>(-::google::protobuf::internal::Infinity())";
|
||||
} else if (value != value) {
|
||||
return "static_cast<float>(::google::protobuf::internal::NaN())";
|
||||
@ -450,8 +450,8 @@ string GlobalInitDefaultsName(const string& filename) {
|
||||
}
|
||||
|
||||
// Return the name of the AssignDescriptors() function for a given file.
|
||||
string GlobalAssignDescriptorsName(const string& filename) {
|
||||
return "protobuf_AssignDesc_" + FilenameIdentifier(filename);
|
||||
string GlobalOffsetTableName(const string& filename) {
|
||||
return "protobuf_Offsets_" + FilenameIdentifier(filename);
|
||||
}
|
||||
|
||||
// Return the name of the ShutdownFile() function for a given file.
|
||||
@ -602,7 +602,7 @@ static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
|
||||
|
||||
static void GenerateUtf8CheckCode(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const map<string, string>& variables,
|
||||
const std::map<string, string>& variables,
|
||||
const char* parameters,
|
||||
const char* strict_function,
|
||||
const char* verify_function,
|
||||
@ -652,7 +652,7 @@ static void GenerateUtf8CheckCode(const FieldDescriptor* field,
|
||||
|
||||
void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const map<string, string>& variables,
|
||||
const std::map<string, string>& variables,
|
||||
const char* parameters,
|
||||
io::Printer* printer) {
|
||||
GenerateUtf8CheckCode(field, options, for_parse, variables, parameters,
|
||||
@ -662,7 +662,7 @@ void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
|
||||
|
||||
void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const map<string, string>& variables,
|
||||
const std::map<string, string>& variables,
|
||||
const char* parameters,
|
||||
io::Printer* printer) {
|
||||
GenerateUtf8CheckCode(field, options, for_parse, variables, parameters,
|
||||
|
@ -150,8 +150,8 @@ string GlobalAddDescriptorsName(const string& filename);
|
||||
// Return the name of the InitDefaults() function for a given file.
|
||||
string GlobalInitDefaultsName(const string& filename);
|
||||
|
||||
// Return the name of the AssignDescriptors() function for a given file.
|
||||
string GlobalAssignDescriptorsName(const string& filename);
|
||||
// Return the name of the offset table function for a given file.
|
||||
string GlobalOffsetTableName(const string& filename);
|
||||
|
||||
// Return the qualified C++ name for a file level symbol.
|
||||
string QualifiedFileLevelSymbol(const string& package, const string& name);
|
||||
@ -269,13 +269,13 @@ bool IsWellKnownMessage(const FileDescriptor* descriptor);
|
||||
|
||||
void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const map<string, string>& variables,
|
||||
const std::map<string, string>& variables,
|
||||
const char* parameters,
|
||||
io::Printer* printer);
|
||||
|
||||
void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const map<string, string>& variables,
|
||||
const std::map<string, string>& variables,
|
||||
const char* parameters, io::Printer* printer);
|
||||
|
||||
inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
|
||||
|
@ -45,10 +45,10 @@ bool IsProto3Field(const FieldDescriptor* field_descriptor) {
|
||||
}
|
||||
|
||||
void SetMessageVariables(const FieldDescriptor* descriptor,
|
||||
map<string, string>* variables,
|
||||
std::map<string, string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
(*variables)["type"] = FieldMessageTypeName(descriptor);
|
||||
(*variables)["type"] = ClassName(descriptor->message_type(), false);
|
||||
(*variables)["stream_writer"] =
|
||||
(*variables)["declared_type"] +
|
||||
(HasFastArraySerialization(descriptor->message_type()->file(), options)
|
||||
@ -137,7 +137,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
|
||||
void MapFieldGenerator::
|
||||
GenerateInlineAccessorDefinitions(io::Printer* printer,
|
||||
bool is_inline) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["inline"] = is_inline ? "inline" : "";
|
||||
printer->Print(variables,
|
||||
"$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
|
||||
@ -154,7 +154,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
|
||||
|
||||
void MapFieldGenerator::
|
||||
GenerateClearingCode(io::Printer* printer) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
|
||||
printer->Print(variables, "$this_message$$name$_.Clear();\n");
|
||||
}
|
||||
@ -173,13 +173,19 @@ void MapFieldGenerator::
|
||||
GenerateConstructorCode(io::Printer* printer) const {
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
printer->Print(variables_,
|
||||
"$name$_.SetAssignDescriptorCallback(\n"
|
||||
" protobuf_AssignDescriptorsOnce);\n"
|
||||
"$name$_.SetEntryDescriptor(\n"
|
||||
" &$type$_descriptor_);\n");
|
||||
"$name$_.SetAssignDescriptorCallback(\n"
|
||||
" protobuf_AssignDescriptorsOnce);\n"
|
||||
"$name$_.SetEntryDescriptor(\n"
|
||||
" &$type$_descriptor);\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MapFieldGenerator::
|
||||
GenerateCopyConstructorCode(io::Printer* printer) const {
|
||||
GenerateConstructorCode(printer);
|
||||
GenerateMergingCode(printer);
|
||||
}
|
||||
|
||||
void MapFieldGenerator::
|
||||
GenerateMergeFromCodedStream(io::Printer* printer) const {
|
||||
const FieldDescriptor* key_field =
|
||||
@ -252,7 +258,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
|
||||
}
|
||||
|
||||
static void GenerateSerializationLoop(io::Printer* printer,
|
||||
const map<string, string>& variables,
|
||||
const std::map<string, string>& variables,
|
||||
bool supports_arenas,
|
||||
const string& utf8_check,
|
||||
const string& loop_header,
|
||||
@ -291,17 +297,17 @@ static void GenerateSerializationLoop(io::Printer* printer,
|
||||
|
||||
void MapFieldGenerator::
|
||||
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Write" +
|
||||
variables["stream_writer"] + "(\n " +
|
||||
variables["number"] + ", *entry, output)";
|
||||
variables["deterministic"] = "output->IsSerializationDeterminstic()";
|
||||
variables["deterministic"] = "output->IsSerializationDeterministic()";
|
||||
GenerateSerializeWithCachedSizes(printer, variables);
|
||||
}
|
||||
|
||||
void MapFieldGenerator::
|
||||
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
|
||||
map<string, string> variables(variables_);
|
||||
std::map<string, string> variables(variables_);
|
||||
variables["write_entry"] =
|
||||
"target = ::google::protobuf::internal::WireFormatLite::\n"
|
||||
" InternalWrite" + variables["declared_type"] +
|
||||
@ -312,7 +318,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateSerializeWithCachedSizes(
|
||||
io::Printer* printer, const map<string, string>& variables) const {
|
||||
io::Printer* printer, const std::map<string, string>& variables) const {
|
||||
printer->Print(variables,
|
||||
"if (!this->$name$().empty()) {\n");
|
||||
printer->Indent();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user