Integrated internal changes from Google
This commit is contained in:
parent
96b535cc2f
commit
0400cca323
@ -243,3 +243,4 @@ public class ProtoCaliperBenchmark {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,3 +115,4 @@ class Benchmark:
|
||||
if __name__ == "__main__":
|
||||
for i in range(2, len(sys.argv)):
|
||||
run_one_test(sys.argv[i])
|
||||
|
||||
|
@ -79,20 +79,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" inc
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h" include\google\protobuf\service.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomic_sequence_num.h" include\google\protobuf\stubs\atomic_sequence_num.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops.h" include\google\protobuf\stubs\atomicops.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm64_gcc.h" include\google\protobuf\stubs\atomicops_internals_arm64_gcc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h" include\google\protobuf\stubs\atomicops_internals_arm_gcc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h" include\google\protobuf\stubs\atomicops_internals_arm_qnx.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h" include\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_gcc.h" include\google\protobuf\stubs\atomicops_internals_generic_gcc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h" include\google\protobuf\stubs\atomicops_internals_mips_gcc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h" include\google\protobuf\stubs\atomicops_internals_power.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_ppc_gcc.h" include\google\protobuf\stubs\atomicops_internals_ppc_gcc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h" include\google\protobuf\stubs\atomicops_internals_solaris.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h" include\google\protobuf\stubs\atomicops_internals_tsan.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h" include\google\protobuf\stubs\atomicops_internals_x86_gcc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h" include\google\protobuf\stubs\atomicops_internals_x86_msvc.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" include\google\protobuf\stubs\bytestream.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h
|
||||
@ -105,8 +91,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" includ
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h" include\google\protobuf\stubs\once.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h" include\google\protobuf\stubs\platform_macros.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h" include\google\protobuf\stubs\port.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h" include\google\protobuf\stubs\scoped_ptr.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h" include\google\protobuf\stubs\shared_ptr.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h" include\google\protobuf\stubs\singleton.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h" include\google\protobuf\stubs\status.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h" include\google\protobuf\stubs\stl_util.h
|
||||
|
@ -10,13 +10,10 @@ set(libprotobuf_lite_files
|
||||
${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/message_lite.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/common.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/int128.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/io_win32.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/once.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/status.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/statusor.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece.cc
|
||||
@ -38,7 +35,6 @@ set(libprotobuf_lite_includes
|
||||
${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.h
|
||||
${protobuf_source_dir}/src/google/protobuf/message_lite.h
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field.h
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.h
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/common.h
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/int128.h
|
||||
|
@ -155,7 +155,8 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/preserve_unknown_enum_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/proto3_arena_lite_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/proto3_arena_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.cc
|
||||
# TODO(b/74491957) Make this unittest work
|
||||
# ${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/reflection_ops_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field_reflection_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
|
||||
@ -163,7 +164,6 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/int128_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/io_win32_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/once_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/statusor_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece_unittest.cc
|
||||
@ -172,7 +172,6 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/strutil_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/template_util_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/time_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/type_traits_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util_test.cc
|
||||
|
@ -1910,6 +1910,10 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||
{
|
||||
TestAllTypesProto3 messageProto3;
|
||||
TestAllTypesProto2 messageProto2;
|
||||
//TODO(yilunchong): update this behavior when unknown field's behavior
|
||||
// changed in open source. Also delete
|
||||
// Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
|
||||
// from failure list of python_cpp python java
|
||||
TestUnknownMessage(messageProto3, true);
|
||||
TestUnknownMessage(messageProto2, false);
|
||||
}
|
||||
|
@ -45,3 +45,4 @@ Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValu
|
||||
Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||
Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
|
@ -19,3 +19,4 @@ Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_0
|
||||
Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_1
|
||||
Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_2
|
||||
Required.Proto3.ProtobufInput.IllegalZeroFieldNum_Case_3
|
||||
Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
|
@ -52,3 +52,4 @@ Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32
|
||||
Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64
|
||||
Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32
|
||||
Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64
|
||||
Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
|
@ -124,6 +124,16 @@ public abstract class AbstractMessage
|
||||
|
||||
protected int memoizedSize = -1;
|
||||
|
||||
@Override
|
||||
int getMemoizedSerializedSize() {
|
||||
return memoizedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setMemoizedSerializedSize(int size) {
|
||||
memoizedSize = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSize;
|
||||
|
@ -99,6 +99,16 @@ public abstract class AbstractMessageLite<
|
||||
codedOutput.flush();
|
||||
}
|
||||
|
||||
// We'd like these to be abstract but some folks are extending this class directly. They shouldn't
|
||||
// be doing that and they should feel bad.
|
||||
int getMemoizedSerializedSize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
void setMemoizedSerializedSize(int size) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Package private helper method for AbstractParser to create
|
||||
|
@ -81,6 +81,18 @@ final class BooleanArrayList extends AbstractProtobufList<Boolean>
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
ensureIsMutable();
|
||||
if (toIndex < fromIndex) {
|
||||
throw new IndexOutOfBoundsException("toIndex < fromIndex");
|
||||
}
|
||||
|
||||
System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
|
||||
size -= (toIndex - fromIndex);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -246,7 +258,9 @@ final class BooleanArrayList extends AbstractProtobufList<Boolean>
|
||||
ensureIsMutable();
|
||||
ensureIndexInRange(index);
|
||||
boolean value = array[index];
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
if (index < size - 1) {
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
}
|
||||
size--;
|
||||
modCount++;
|
||||
return value;
|
||||
|
@ -66,11 +66,9 @@ public abstract class CodedInputStream {
|
||||
|
||||
/**
|
||||
* Whether to enable our custom UTF-8 decode codepath which does not use {@link StringCoding}.
|
||||
* Enabled by default, disable by setting
|
||||
* {@code -Dcom.google.protobuf.enableCustomutf8Decode=false} in JVM args.
|
||||
* Currently disabled.
|
||||
*/
|
||||
private static final boolean ENABLE_CUSTOM_UTF8_DECODE
|
||||
= !"false".equals(System.getProperty("com.google.protobuf.enableCustomUtf8Decode"));
|
||||
private static final boolean ENABLE_CUSTOM_UTF8_DECODE = false;
|
||||
|
||||
/** Visible for subclasses. See setRecursionLimit() */
|
||||
int recursionDepth;
|
||||
|
@ -377,6 +377,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
public abstract void writeMessage(final int fieldNumber, final MessageLite value)
|
||||
throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Write a MessageSet extension field to the stream. For historical reasons,
|
||||
* the wire format differs from normal fields.
|
||||
@ -481,6 +482,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
// Abstract to avoid overhead of additional virtual method calls.
|
||||
public abstract void writeMessageNoTag(final MessageLite value) throws IOException;
|
||||
|
||||
|
||||
//=================================================================
|
||||
|
||||
@ExperimentalApi
|
||||
@ -666,6 +668,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* MessageSet extension to the stream. For historical reasons,
|
||||
@ -913,6 +916,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
return computeLengthDelimitedFieldSize(value.getSerializedSize());
|
||||
}
|
||||
|
||||
|
||||
static int computeLengthDelimitedFieldSize(int fieldLength) {
|
||||
return computeUInt32SizeNoTag(fieldLength) + fieldLength;
|
||||
}
|
||||
@ -1049,6 +1053,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a {@code group} field to the stream.
|
||||
*
|
||||
@ -1059,6 +1064,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
value.writeTo(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code group} field, including tag.
|
||||
@ -1070,6 +1076,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code group} field.
|
||||
@ -1079,6 +1086,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
return value.getSerializedSize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode and write a varint. {@code value} is treated as
|
||||
* unsigned, so it won't be sign-extended if negative.
|
||||
@ -1273,6 +1281,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
writeMessageNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
|
||||
throws IOException {
|
||||
@ -1297,6 +1306,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
value.writeTo(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void write(byte value) throws IOException {
|
||||
try {
|
||||
@ -1608,6 +1618,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
writeMessageNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
|
||||
throws IOException {
|
||||
@ -1632,6 +1643,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
value.writeTo(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte value) throws IOException {
|
||||
try {
|
||||
@ -1928,6 +1940,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
writeMessageNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeMessageSetExtension(int fieldNumber, MessageLite value) throws IOException {
|
||||
writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
|
||||
@ -1950,6 +1963,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
value.writeTo(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte value) throws IOException {
|
||||
if (position >= limit) {
|
||||
@ -2456,6 +2470,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
writeMessageNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
|
||||
throws IOException {
|
||||
@ -2480,6 +2495,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
value.writeTo(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte value) throws IOException {
|
||||
if (position == limit) {
|
||||
@ -2759,6 +2775,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
writeMessageNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
|
||||
throws IOException {
|
||||
@ -2783,6 +2800,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
value.writeTo(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte value) throws IOException {
|
||||
if (position == limit) {
|
||||
|
@ -81,6 +81,18 @@ final class DoubleArrayList extends AbstractProtobufList<Double>
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
ensureIsMutable();
|
||||
if (toIndex < fromIndex) {
|
||||
throw new IndexOutOfBoundsException("toIndex < fromIndex");
|
||||
}
|
||||
|
||||
System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
|
||||
size -= (toIndex - fromIndex);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -247,7 +259,9 @@ final class DoubleArrayList extends AbstractProtobufList<Double>
|
||||
ensureIsMutable();
|
||||
ensureIndexInRange(index);
|
||||
double value = array[index];
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
if (index < size - 1) {
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
}
|
||||
size--;
|
||||
modCount++;
|
||||
return value;
|
||||
|
@ -339,6 +339,20 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
this.fields = FieldSet.newFieldSet();
|
||||
this.unknownFields = UnknownFieldSet.getDefaultInstance();
|
||||
this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()];
|
||||
// A MapEntry has all of its fields present at all times.
|
||||
if (type.getOptions().getMapEntry()) {
|
||||
populateMapEntry();
|
||||
}
|
||||
}
|
||||
|
||||
private void populateMapEntry() {
|
||||
for (FieldDescriptor field : type.getFields()) {
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
fields.setField(field, getDefaultInstance(field.getMessageType()));
|
||||
} else {
|
||||
fields.setField(field, field.getDefaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
@ -351,6 +365,10 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
} else {
|
||||
fields.clear();
|
||||
}
|
||||
// A MapEntry has all of its fields present at all times.
|
||||
if (type.getOptions().getMapEntry()) {
|
||||
populateMapEntry();
|
||||
}
|
||||
unknownFields = UnknownFieldSet.getDefaultInstance();
|
||||
return this;
|
||||
}
|
||||
|
@ -81,6 +81,18 @@ final class FloatArrayList extends AbstractProtobufList<Float>
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
ensureIsMutable();
|
||||
if (toIndex < fromIndex) {
|
||||
throw new IndexOutOfBoundsException("toIndex < fromIndex");
|
||||
}
|
||||
|
||||
System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
|
||||
size -= (toIndex - fromIndex);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -246,7 +258,9 @@ final class FloatArrayList extends AbstractProtobufList<Float>
|
||||
ensureIsMutable();
|
||||
ensureIndexInRange(index);
|
||||
float value = array[index];
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
if (index < size - 1) {
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
}
|
||||
size--;
|
||||
modCount++;
|
||||
return value;
|
||||
|
@ -230,9 +230,13 @@ public abstract class GeneratedMessageLite<
|
||||
* Called by subclasses to complete parsing. For use by generated code only.
|
||||
*/
|
||||
protected void makeImmutable() {
|
||||
// BEGIN REGULAR
|
||||
dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
|
||||
|
||||
unknownFields.makeImmutable();
|
||||
// END REGULAR
|
||||
// BEGIN EXPERIMENTAL
|
||||
// Protobuf.getInstance().schemaFor(this).makeImmutable(this);
|
||||
// END EXPERIMENTAL
|
||||
}
|
||||
|
||||
protected final <
|
||||
@ -269,15 +273,15 @@ public abstract class GeneratedMessageLite<
|
||||
* For use by generated code only.
|
||||
*/
|
||||
public static enum MethodToInvoke {
|
||||
IS_INITIALIZED,
|
||||
// BEGIN REGULAR
|
||||
IS_INITIALIZED,
|
||||
VISIT,
|
||||
MERGE_FROM_STREAM,
|
||||
MAKE_IMMUTABLE,
|
||||
// END REGULAR
|
||||
// Rely on/modify instance state
|
||||
GET_MEMOIZED_IS_INITIALIZED,
|
||||
SET_MEMOIZED_IS_INITIALIZED,
|
||||
MERGE_FROM_STREAM,
|
||||
MAKE_IMMUTABLE,
|
||||
|
||||
// Rely on static state
|
||||
NEW_MUTABLE_INSTANCE,
|
||||
@ -339,6 +343,16 @@ public abstract class GeneratedMessageLite<
|
||||
}
|
||||
// END REGULAR
|
||||
|
||||
@Override
|
||||
int getMemoizedSerializedSize() {
|
||||
return memoizedSerializedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setMemoizedSerializedSize(int size) {
|
||||
memoizedSerializedSize = size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -448,6 +462,28 @@ public abstract class GeneratedMessageLite<
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(byte[] input, int offset, int length)
|
||||
throws InvalidProtocolBufferException {
|
||||
// BEGIN REGULAR
|
||||
return super.mergeFrom(input, offset, length);
|
||||
// END REGULAR
|
||||
// BEGIN EXPERIMENTAL
|
||||
// copyOnWrite();
|
||||
// try {
|
||||
// Protobuf.getInstance().schemaFor(instance).mergeFrom(
|
||||
// instance, input, offset, offset + length, new ArrayDecoders.Registers());
|
||||
// } catch (InvalidProtocolBufferException e) {
|
||||
// throw e;
|
||||
// } catch (IndexOutOfBoundsException e) {
|
||||
// throw InvalidProtocolBufferException.truncatedMessage();
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException("Reading from byte array should not throw IOException.", e);
|
||||
// }
|
||||
// return (BuilderType) this;
|
||||
// END EXPERIMENTAL
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
@ -455,7 +491,13 @@ public abstract class GeneratedMessageLite<
|
||||
throws IOException {
|
||||
copyOnWrite();
|
||||
try {
|
||||
// BEGIN REGULAR
|
||||
instance.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
|
||||
// END REGULAR
|
||||
// BEGIN EXPERIMENTAL
|
||||
// Protobuf.getInstance().schemaFor(instance).mergeFrom(
|
||||
// instance, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
|
||||
// END EXPERIMENTAL
|
||||
} catch (RuntimeException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw (IOException) e.getCause();
|
||||
@ -576,9 +618,7 @@ public abstract class GeneratedMessageLite<
|
||||
return parseUnknownField(tag, input);
|
||||
}
|
||||
|
||||
if (extensions.isImmutable()) {
|
||||
extensions = extensions.clone();
|
||||
}
|
||||
ensureExtensionsAreMutable();
|
||||
|
||||
if (packed) {
|
||||
int length = input.readRawVarint32();
|
||||
@ -794,10 +834,18 @@ public abstract class GeneratedMessageLite<
|
||||
if (subBuilder == null) {
|
||||
subBuilder = extension.getMessageDefaultInstance().newBuilderForType();
|
||||
}
|
||||
rawBytes.newCodedInput().readMessage(subBuilder, extensionRegistry);
|
||||
subBuilder.mergeFrom(rawBytes, extensionRegistry);
|
||||
MessageLite value = subBuilder.build();
|
||||
|
||||
extensions.setField(extension.descriptor, extension.singularToFieldSetType(value));
|
||||
ensureExtensionsAreMutable().setField(
|
||||
extension.descriptor, extension.singularToFieldSetType(value));
|
||||
}
|
||||
|
||||
private FieldSet<ExtensionDescriptor> ensureExtensionsAreMutable() {
|
||||
if (extensions.isImmutable()) {
|
||||
extensions = extensions.clone();
|
||||
}
|
||||
return extensions;
|
||||
}
|
||||
|
||||
private void verifyExtensionContainingType(
|
||||
@ -869,10 +917,12 @@ public abstract class GeneratedMessageLite<
|
||||
@Override
|
||||
protected final void makeImmutable() {
|
||||
super.makeImmutable();
|
||||
|
||||
// BEGIN REGULAR
|
||||
extensions.makeImmutable();
|
||||
// END REGULAR
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used by subclasses to serialize extensions. Extension ranges may be
|
||||
* interleaved with field numbers, but we must write them in canonical
|
||||
@ -1468,8 +1518,13 @@ public abstract class GeneratedMessageLite<
|
||||
if (memoizedIsInitialized == 0) {
|
||||
return false;
|
||||
}
|
||||
// BEGIN EXPERIMENTAL
|
||||
// boolean isInitialized = Protobuf.getInstance().schemaFor(message).isInitialized(message);
|
||||
// END EXPERIMENTAL
|
||||
// BEGIN REGULAR
|
||||
boolean isInitialized =
|
||||
message.dynamicMethod(MethodToInvoke.IS_INITIALIZED, Boolean.FALSE) != null;
|
||||
// END REGULAR
|
||||
if (shouldMemoize) {
|
||||
message.dynamicMethod(
|
||||
MethodToInvoke.SET_MEMOIZED_IS_INITIALIZED, isInitialized ? message : null);
|
||||
@ -1477,10 +1532,6 @@ public abstract class GeneratedMessageLite<
|
||||
return isInitialized;
|
||||
}
|
||||
|
||||
protected static final <T extends GeneratedMessageLite<T, ?>> void makeImmutable(T message) {
|
||||
message.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
|
||||
}
|
||||
|
||||
protected static IntList emptyIntList() {
|
||||
return IntArrayList.emptyList();
|
||||
}
|
||||
@ -1560,6 +1611,11 @@ public abstract class GeneratedMessageLite<
|
||||
throws InvalidProtocolBufferException {
|
||||
return GeneratedMessageLite.parsePartialFrom(defaultInstance, input, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parsePartialFrom(byte[] input) throws InvalidProtocolBufferException {
|
||||
return GeneratedMessageLite.parsePartialFrom(defaultInstance, input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1573,8 +1629,21 @@ public abstract class GeneratedMessageLite<
|
||||
@SuppressWarnings("unchecked") // Guaranteed by protoc
|
||||
T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
|
||||
try {
|
||||
// BEGIN REGULAR
|
||||
result.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
|
||||
// END REGULAR
|
||||
// BEGIN EXPERIMENTAL
|
||||
// Protobuf.getInstance().schemaFor(result).mergeFrom(
|
||||
// result, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
|
||||
// END EXPERIMENTAL
|
||||
result.makeImmutable();
|
||||
// BEGIN EXPERIMENTAL
|
||||
// } catch (IOException e) {
|
||||
// if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
// throw (InvalidProtocolBufferException) e.getCause();
|
||||
// }
|
||||
// throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(result);
|
||||
// END EXPERIMENTAL
|
||||
} catch (RuntimeException e) {
|
||||
if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
throw (InvalidProtocolBufferException) e.getCause();
|
||||
@ -1584,6 +1653,34 @@ public abstract class GeneratedMessageLite<
|
||||
return result;
|
||||
}
|
||||
|
||||
/** A static helper method for parsing a partial from byte array. */
|
||||
static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(T instance, byte[] input)
|
||||
throws InvalidProtocolBufferException {
|
||||
// BEGIN REGULAR
|
||||
return parsePartialFrom(instance, input, ExtensionRegistryLite.getEmptyRegistry());
|
||||
// END REGULAR
|
||||
// BEGIN EXPERIMENTAL
|
||||
// @SuppressWarnings("unchecked") // Guaranteed by protoc
|
||||
// T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
|
||||
// try {
|
||||
// Protobuf.getInstance().schemaFor(result).mergeFrom(
|
||||
// result, input, 0, input.length, new ArrayDecoders.Registers());
|
||||
// result.makeImmutable();
|
||||
// if (result.memoizedHashCode != 0) {
|
||||
// throw new RuntimeException();
|
||||
// }
|
||||
// } catch (IOException e) {
|
||||
// if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
// throw (InvalidProtocolBufferException) e.getCause();
|
||||
// }
|
||||
// throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(result);
|
||||
// } catch (IndexOutOfBoundsException e) {
|
||||
// throw InvalidProtocolBufferException.truncatedMessage().setUnfinishedMessage(result);
|
||||
// }
|
||||
// return result;
|
||||
// END EXPERIMENTAL
|
||||
}
|
||||
|
||||
protected static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
|
||||
T defaultInstance,
|
||||
CodedInputStream input)
|
||||
@ -1680,8 +1777,7 @@ public abstract class GeneratedMessageLite<
|
||||
protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
|
||||
T defaultInstance, byte[] data)
|
||||
throws InvalidProtocolBufferException {
|
||||
return checkMessageInitialized(
|
||||
parsePartialFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry()));
|
||||
return checkMessageInitialized(parsePartialFrom(defaultInstance, data));
|
||||
}
|
||||
|
||||
// Validates last tag.
|
||||
|
@ -81,6 +81,18 @@ final class IntArrayList extends AbstractProtobufList<Integer>
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
ensureIsMutable();
|
||||
if (toIndex < fromIndex) {
|
||||
throw new IndexOutOfBoundsException("toIndex < fromIndex");
|
||||
}
|
||||
|
||||
System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
|
||||
size -= (toIndex - fromIndex);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -246,7 +258,9 @@ final class IntArrayList extends AbstractProtobufList<Integer>
|
||||
ensureIsMutable();
|
||||
ensureIndexInRange(index);
|
||||
int value = array[index];
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
if (index < size - 1) {
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
}
|
||||
size--;
|
||||
modCount++;
|
||||
return value;
|
||||
|
@ -81,6 +81,18 @@ final class LongArrayList extends AbstractProtobufList<Long>
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
ensureIsMutable();
|
||||
if (toIndex < fromIndex) {
|
||||
throw new IndexOutOfBoundsException("toIndex < fromIndex");
|
||||
}
|
||||
|
||||
System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
|
||||
size -= (toIndex - fromIndex);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -246,7 +258,9 @@ final class LongArrayList extends AbstractProtobufList<Long>
|
||||
ensureIsMutable();
|
||||
ensureIndexInRange(index);
|
||||
long value = array[index];
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
if (index < size - 1) {
|
||||
System.arraycopy(array, index + 1, array, index, size - index);
|
||||
}
|
||||
size--;
|
||||
modCount++;
|
||||
return value;
|
||||
|
@ -31,6 +31,7 @@
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -38,20 +39,18 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Helps generate {@link String} representations of {@link MessageLite} protos.
|
||||
*/
|
||||
// TODO(dweis): Fix map fields.
|
||||
/** Helps generate {@link String} representations of {@link MessageLite} protos. */
|
||||
final class MessageLiteToString {
|
||||
|
||||
private static final String LIST_SUFFIX = "List";
|
||||
private static final String BUILDER_LIST_SUFFIX = "OrBuilderList";
|
||||
private static final String MAP_SUFFIX = "Map";
|
||||
private static final String BYTES_SUFFIX = "Bytes";
|
||||
|
||||
|
||||
/**
|
||||
* Returns a {@link String} representation of the {@link MessageLite} object. The first line of
|
||||
* Returns a {@link String} representation of the {@link MessageLite} object. The first line of
|
||||
* the {@code String} representation representation includes a comment string to uniquely identify
|
||||
* the objcet instance. This acts as an indicator that this should not be relied on for
|
||||
* the object instance. This acts as an indicator that this should not be relied on for
|
||||
* comparisons.
|
||||
*
|
||||
* <p>For use by generated code only.
|
||||
@ -71,8 +70,9 @@ final class MessageLiteToString {
|
||||
*/
|
||||
private static void reflectivePrintWithIndent(
|
||||
MessageLite messageLite, StringBuilder buffer, int indent) {
|
||||
// Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(), and
|
||||
// getFooList() which might be useful for building an object's string representation.
|
||||
// Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(),
|
||||
// getFooList() and getFooMap() which might be useful for building an object's string
|
||||
// representation.
|
||||
Map<String, Method> nameToNoArgMethod = new HashMap<String, Method>();
|
||||
Map<String, Method> nameToMethod = new HashMap<String, Method>();
|
||||
Set<String> getters = new TreeSet<String>();
|
||||
@ -89,12 +89,16 @@ final class MessageLiteToString {
|
||||
|
||||
for (String getter : getters) {
|
||||
String suffix = getter.replaceFirst("get", "");
|
||||
if (suffix.endsWith(LIST_SUFFIX) && !suffix.endsWith(BUILDER_LIST_SUFFIX)) {
|
||||
String camelCase = suffix.substring(0, 1).toLowerCase()
|
||||
+ suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
|
||||
if (suffix.endsWith(LIST_SUFFIX)
|
||||
&& !suffix.endsWith(BUILDER_LIST_SUFFIX)
|
||||
// Sometimes people have fields named 'list' that aren't repeated.
|
||||
&& !suffix.equals(LIST_SUFFIX)) {
|
||||
String camelCase =
|
||||
suffix.substring(0, 1).toLowerCase()
|
||||
+ suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
|
||||
// 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);
|
||||
// only works if the method names have not been proguarded out or renamed.
|
||||
Method listMethod = nameToNoArgMethod.get(getter);
|
||||
if (listMethod != null && listMethod.getReturnType().equals(List.class)) {
|
||||
printField(
|
||||
buffer,
|
||||
@ -104,6 +108,30 @@ final class MessageLiteToString {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (suffix.endsWith(MAP_SUFFIX)
|
||||
// Sometimes people have fields named 'map' that aren't maps.
|
||||
&& !suffix.equals(MAP_SUFFIX)) {
|
||||
String camelCase =
|
||||
suffix.substring(0, 1).toLowerCase()
|
||||
+ suffix.substring(1, suffix.length() - MAP_SUFFIX.length());
|
||||
// Try to reflectively get the value and toString() the field as if it were a map. This only
|
||||
// works if the method names have not been proguarded out or renamed.
|
||||
Method mapMethod = nameToNoArgMethod.get(getter);
|
||||
if (mapMethod != null
|
||||
&& mapMethod.getReturnType().equals(Map.class)
|
||||
// Skip the deprecated getter method with no prefix "Map" when the field name ends with
|
||||
// "map".
|
||||
&& !mapMethod.isAnnotationPresent(Deprecated.class)
|
||||
// Skip the internal mutable getter method.
|
||||
&& Modifier.isPublic(mapMethod.getModifiers())) {
|
||||
printField(
|
||||
buffer,
|
||||
indent,
|
||||
camelCaseToSnakeCase(camelCase),
|
||||
GeneratedMessageLite.invokeOrDie(mapMethod, messageLite));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Method setter = nameToMethod.get("set" + suffix);
|
||||
if (setter == null) {
|
||||
@ -119,22 +147,19 @@ final class MessageLiteToString {
|
||||
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
|
||||
// only works if the method names have not be proguarded out or renamed.
|
||||
// only works if the method names have not been proguarded out or renamed.
|
||||
Method getMethod = nameToNoArgMethod.get("get" + suffix);
|
||||
Method hasMethod = nameToNoArgMethod.get("has" + suffix);
|
||||
// TODO(dweis): Fix proto3 semantics.
|
||||
if (getMethod != null) {
|
||||
Object value = GeneratedMessageLite.invokeOrDie(getMethod, messageLite);
|
||||
final boolean hasValue = hasMethod == null
|
||||
? !isDefaultValue(value)
|
||||
: (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
|
||||
// TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
|
||||
final boolean hasValue =
|
||||
hasMethod == null
|
||||
? !isDefaultValue(value)
|
||||
: (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
|
||||
// TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
|
||||
if (hasValue) {
|
||||
printField(
|
||||
buffer,
|
||||
indent,
|
||||
camelCaseToSnakeCase(camelCase),
|
||||
value);
|
||||
printField(buffer, indent, camelCaseToSnakeCase(camelCase), value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -153,7 +178,7 @@ final class MessageLiteToString {
|
||||
((GeneratedMessageLite<?, ?>) messageLite).unknownFields.printWithIndent(buffer, indent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean isDefaultValue(Object o) {
|
||||
if (o instanceof Boolean) {
|
||||
return !((Boolean) o);
|
||||
@ -179,7 +204,7 @@ final class MessageLiteToString {
|
||||
if (o instanceof java.lang.Enum<?>) { // Catches oneof enums.
|
||||
return ((java.lang.Enum<?>) o).ordinal() == 0;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -201,6 +226,13 @@ final class MessageLiteToString {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (object instanceof Map<?, ?>) {
|
||||
Map<?, ?> map = (Map<?, ?>) object;
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
printField(buffer, indent, name, entry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.append('\n');
|
||||
for (int i = 0; i < indent; i++) {
|
||||
@ -220,11 +252,21 @@ final class MessageLiteToString {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append("}");
|
||||
} else if (object instanceof Map.Entry<?, ?>) {
|
||||
buffer.append(" {");
|
||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
|
||||
printField(buffer, indent + 2, "key", entry.getKey());
|
||||
printField(buffer, indent + 2, "value", entry.getValue());
|
||||
buffer.append("\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append("}");
|
||||
} else {
|
||||
buffer.append(": ").append(object.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final String camelCaseToSnakeCase(String camelCase) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < camelCase.length(); i++) {
|
||||
|
@ -987,7 +987,7 @@ public final class TextFormat {
|
||||
nextToken();
|
||||
return false;
|
||||
} else {
|
||||
throw parseException("Expected \"true\" or \"false\".");
|
||||
throw parseException("Expected \"true\" or \"false\". Found \"" + currentToken + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1311,13 +1311,17 @@ public final class TextFormat {
|
||||
}
|
||||
|
||||
private final boolean allowUnknownFields;
|
||||
private final boolean allowUnknownEnumValues;
|
||||
private final SingularOverwritePolicy singularOverwritePolicy;
|
||||
private TextFormatParseInfoTree.Builder parseInfoTreeBuilder;
|
||||
|
||||
private Parser(
|
||||
boolean allowUnknownFields, SingularOverwritePolicy singularOverwritePolicy,
|
||||
boolean allowUnknownFields,
|
||||
boolean allowUnknownEnumValues,
|
||||
SingularOverwritePolicy singularOverwritePolicy,
|
||||
TextFormatParseInfoTree.Builder parseInfoTreeBuilder) {
|
||||
this.allowUnknownFields = allowUnknownFields;
|
||||
this.allowUnknownEnumValues = allowUnknownEnumValues;
|
||||
this.singularOverwritePolicy = singularOverwritePolicy;
|
||||
this.parseInfoTreeBuilder = parseInfoTreeBuilder;
|
||||
}
|
||||
@ -1334,6 +1338,7 @@ public final class TextFormat {
|
||||
*/
|
||||
public static class Builder {
|
||||
private boolean allowUnknownFields = false;
|
||||
private boolean allowUnknownEnumValues = false;
|
||||
private SingularOverwritePolicy singularOverwritePolicy =
|
||||
SingularOverwritePolicy.ALLOW_SINGULAR_OVERWRITES;
|
||||
private TextFormatParseInfoTree.Builder parseInfoTreeBuilder = null;
|
||||
@ -1355,7 +1360,10 @@ public final class TextFormat {
|
||||
|
||||
public Parser build() {
|
||||
return new Parser(
|
||||
allowUnknownFields, singularOverwritePolicy, parseInfoTreeBuilder);
|
||||
allowUnknownFields,
|
||||
allowUnknownEnumValues,
|
||||
singularOverwritePolicy,
|
||||
parseInfoTreeBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1419,7 +1427,7 @@ public final class TextFormat {
|
||||
return text;
|
||||
}
|
||||
|
||||
// Check both unknown fields and unknown extensions and log warming messages
|
||||
// Check both unknown fields and unknown extensions and log warning messages
|
||||
// or throw exceptions according to the flag.
|
||||
private void checkUnknownFields(final List<String> unknownFields)
|
||||
throws ParseException {
|
||||
@ -1737,17 +1745,40 @@ public final class TextFormat {
|
||||
final int number = tokenizer.consumeInt32();
|
||||
value = enumType.findValueByNumber(number);
|
||||
if (value == null) {
|
||||
throw tokenizer.parseExceptionPreviousToken(
|
||||
"Enum type \"" + enumType.getFullName()
|
||||
+ "\" has no value with number " + number + '.');
|
||||
String unknownValueMsg =
|
||||
"Enum type \""
|
||||
+ enumType.getFullName()
|
||||
+ "\" has no value with number "
|
||||
+ number
|
||||
+ '.';
|
||||
if (allowUnknownEnumValues) {
|
||||
logger.warning(unknownValueMsg);
|
||||
return;
|
||||
} else {
|
||||
throw tokenizer.parseExceptionPreviousToken(
|
||||
"Enum type \""
|
||||
+ enumType.getFullName()
|
||||
+ "\" has no value with number "
|
||||
+ number
|
||||
+ '.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final String id = tokenizer.consumeIdentifier();
|
||||
value = enumType.findValueByName(id);
|
||||
if (value == null) {
|
||||
throw tokenizer.parseExceptionPreviousToken(
|
||||
"Enum type \"" + enumType.getFullName()
|
||||
+ "\" has no value named \"" + id + "\".");
|
||||
String unknownValueMsg =
|
||||
"Enum type \""
|
||||
+ enumType.getFullName()
|
||||
+ "\" has no value named \""
|
||||
+ id
|
||||
+ "\".";
|
||||
if (allowUnknownEnumValues) {
|
||||
logger.warning(unknownValueMsg);
|
||||
return;
|
||||
} else {
|
||||
throw tokenizer.parseExceptionPreviousToken(unknownValueMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,14 +295,30 @@ public final class UnknownFieldSetLite {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int hashCode(int[] tags, int count) {
|
||||
int hashCode = 17;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
hashCode = 31 * hashCode + tags[i];
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
private static int hashCode(Object[] objects, int count) {
|
||||
int hashCode = 17;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
hashCode = 31 * hashCode + objects[i].hashCode();
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = 17;
|
||||
|
||||
|
||||
hashCode = 31 * hashCode + count;
|
||||
hashCode = 31 * hashCode + Arrays.hashCode(tags);
|
||||
hashCode = 31 * hashCode + Arrays.deepHashCode(objects);
|
||||
|
||||
hashCode = 31 * hashCode + hashCode(tags, count);
|
||||
hashCode = 31 * hashCode + hashCode(objects, count);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ package com.google.protobuf;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.logging.Level;
|
||||
@ -83,6 +84,7 @@ final class UnsafeUtil {
|
||||
return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
|
||||
}
|
||||
|
||||
|
||||
static long objectFieldOffset(Field field) {
|
||||
return MEMORY_ACCESSOR.objectFieldOffset(field);
|
||||
}
|
||||
@ -287,7 +289,7 @@ final class UnsafeUtil {
|
||||
/**
|
||||
* Gets the {@code sun.misc.Unsafe} instance, or {@code null} if not available on this platform.
|
||||
*/
|
||||
private static sun.misc.Unsafe getUnsafe() {
|
||||
static sun.misc.Unsafe getUnsafe() {
|
||||
sun.misc.Unsafe unsafe = null;
|
||||
try {
|
||||
unsafe =
|
||||
@ -367,6 +369,10 @@ final class UnsafeUtil {
|
||||
clazz.getMethod("objectFieldOffset", Field.class);
|
||||
clazz.getMethod("getLong", Object.class, long.class);
|
||||
|
||||
if (bufferAddressField() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clazz.getMethod("getByte", long.class);
|
||||
clazz.getMethod("putByte", long.class, byte.class);
|
||||
clazz.getMethod("getInt", long.class);
|
||||
@ -387,12 +393,14 @@ final class UnsafeUtil {
|
||||
|
||||
/** Finds the address field within a direct {@link Buffer}. */
|
||||
private static Field bufferAddressField() {
|
||||
return field(Buffer.class, "address", long.class);
|
||||
Field field = field(Buffer.class, "address");
|
||||
return field != null && field.getType() == long.class ? field : null;
|
||||
}
|
||||
|
||||
/** Finds the value field within a {@link String}. */
|
||||
private static Field stringValueField() {
|
||||
return field(String.class, "value", char[].class);
|
||||
Field field = field(String.class, "value");
|
||||
return field != null && field.getType() == char[].class ? field : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,14 +415,11 @@ final class UnsafeUtil {
|
||||
* Gets the field with the given name within the class, or {@code null} if not found. If found,
|
||||
* the field is made accessible.
|
||||
*/
|
||||
private static Field field(Class<?> clazz, String fieldName, Class<?> expectedType) {
|
||||
private static Field field(Class<?> clazz, String fieldName) {
|
||||
Field field;
|
||||
try {
|
||||
field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
if (!field.getType().equals(expectedType)) {
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Failed to access the fields.
|
||||
field = null;
|
||||
|
@ -32,6 +32,7 @@ package com.google.protobuf;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import com.google.protobuf.Internal.BooleanList;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
@ -297,6 +298,20 @@ public class BooleanArrayListTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveEndOfCapacity() {
|
||||
BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addBoolean(true);
|
||||
toRemove.remove(0);
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
public void testSublistRemoveEndOfCapacity() {
|
||||
BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addBoolean(true);
|
||||
toRemove.subList(0, 1).clear();
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
private void assertImmutable(BooleanArrayList list) {
|
||||
|
||||
try {
|
||||
|
@ -34,7 +34,7 @@ import proto2_test_check_utf8.TestCheckUtf8.BytesWrapper;
|
||||
import proto2_test_check_utf8.TestCheckUtf8.StringWrapper;
|
||||
import proto2_test_check_utf8_size.TestCheckUtf8Size.BytesWrapperSize;
|
||||
import proto2_test_check_utf8_size.TestCheckUtf8Size.StringWrapperSize;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -90,14 +90,9 @@ public class CheckUtf8Test extends TestCase {
|
||||
}
|
||||
|
||||
public void testParseRequiredStringWithBadUtf8() throws Exception {
|
||||
ByteString serialized =
|
||||
BytesWrapper.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString();
|
||||
try {
|
||||
StringWrapper.parser().parseFrom(serialized);
|
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
|
||||
} catch (InvalidProtocolBufferException exception) {
|
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
|
||||
}
|
||||
byte[] serialized =
|
||||
BytesWrapper.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteArray();
|
||||
assertParseBadUtf8(StringWrapper.getDefaultInstance(), serialized);
|
||||
}
|
||||
|
||||
public void testBuildRequiredStringWithBadUtf8Size() throws Exception {
|
||||
@ -128,14 +123,36 @@ public class CheckUtf8Test extends TestCase {
|
||||
}
|
||||
|
||||
public void testParseRequiredStringWithBadUtf8Size() throws Exception {
|
||||
ByteString serialized =
|
||||
BytesWrapperSize.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString();
|
||||
byte[] serialized =
|
||||
BytesWrapperSize.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteArray();
|
||||
assertParseBadUtf8(StringWrapperSize.getDefaultInstance(), serialized);
|
||||
}
|
||||
|
||||
private void assertParseBadUtf8(MessageLite defaultInstance, byte[] data) throws Exception {
|
||||
// Check combinations of (parser vs. builder) x (byte[] vs. InputStream)
|
||||
try {
|
||||
StringWrapperSize.parser().parseFrom(serialized);
|
||||
defaultInstance.getParserForType().parseFrom(data);
|
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
|
||||
} catch (InvalidProtocolBufferException exception) {
|
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
|
||||
}
|
||||
try {
|
||||
defaultInstance.newBuilderForType().mergeFrom(data);
|
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
|
||||
} catch (InvalidProtocolBufferException exception) {
|
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
|
||||
}
|
||||
try {
|
||||
defaultInstance.getParserForType().parseFrom(new ByteArrayInputStream(data));
|
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
|
||||
} catch (InvalidProtocolBufferException exception) {
|
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
|
||||
}
|
||||
try {
|
||||
defaultInstance.newBuilderForType().mergeFrom(new ByteArrayInputStream(data));
|
||||
fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
|
||||
} catch (InvalidProtocolBufferException exception) {
|
||||
assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ package com.google.protobuf;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import com.google.protobuf.Internal.DoubleList;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
@ -297,6 +298,20 @@ public class DoubleArrayListTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveEndOfCapacity() {
|
||||
DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addDouble(3);
|
||||
toRemove.remove(0);
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
public void testSublistRemoveEndOfCapacity() {
|
||||
DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addDouble(3);
|
||||
toRemove.subList(0, 1).clear();
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
private void assertImmutable(DoubleArrayList list) {
|
||||
if (list.contains(1D)) {
|
||||
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
|
||||
|
@ -32,6 +32,7 @@ package com.google.protobuf;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import com.google.protobuf.Internal.FloatList;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
@ -297,6 +298,20 @@ public class FloatArrayListTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveEndOfCapacity() {
|
||||
FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addFloat(3);
|
||||
toRemove.remove(0);
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
public void testSublistRemoveEndOfCapacity() {
|
||||
FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addFloat(3);
|
||||
toRemove.subList(0, 1).clear();
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
private void assertImmutable(FloatArrayList list) {
|
||||
if (list.contains(1F)) {
|
||||
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
|
||||
|
@ -32,6 +32,7 @@ package com.google.protobuf;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import com.google.protobuf.Internal.IntList;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
@ -297,6 +298,20 @@ public class IntArrayListTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveEndOfCapacity() {
|
||||
IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addInt(3);
|
||||
toRemove.remove(0);
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
public void testSublistRemoveEndOfCapacity() {
|
||||
IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addInt(3);
|
||||
toRemove.subList(0, 1).clear();
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
private void assertImmutable(IntArrayList list) {
|
||||
if (list.contains(1)) {
|
||||
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ package com.google.protobuf;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import com.google.protobuf.Internal.LongList;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
@ -297,6 +298,20 @@ public class LongArrayListTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveEndOfCapacity() {
|
||||
LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addLong(3);
|
||||
toRemove.remove(0);
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
public void testSublistRemoveEndOfCapacity() {
|
||||
LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(1);
|
||||
toRemove.addLong(3);
|
||||
toRemove.subList(0, 1).clear();
|
||||
assertEquals(0, toRemove.size());
|
||||
}
|
||||
|
||||
private void assertImmutable(LongArrayList list) {
|
||||
if (list.contains(1L)) {
|
||||
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
|
||||
|
@ -788,6 +788,24 @@ public class MapForProto2Test extends TestCase {
|
||||
assertEquals(message.hashCode(), dynamicMessage.hashCode());
|
||||
}
|
||||
|
||||
// Check that DynamicMessage handles map field serialization the same way as generated code
|
||||
// regarding unset key and value field in a map entry.
|
||||
public void testDynamicMessageUnsetKeyAndValue() throws Exception {
|
||||
FieldDescriptor field = f("int32_to_int32_field");
|
||||
|
||||
Message dynamicDefaultInstance =
|
||||
DynamicMessage.getDefaultInstance(TestMap.getDescriptor());
|
||||
Message.Builder builder = dynamicDefaultInstance.newBuilderForType();
|
||||
// Add an entry without key and value.
|
||||
builder.addRepeatedField(field, builder.newBuilderForField(field).build());
|
||||
Message message = builder.build();
|
||||
ByteString bytes = message.toByteString();
|
||||
// Parse it back to the same generated type.
|
||||
Message generatedMessage = TestMap.parseFrom(bytes);
|
||||
// Assert the serialized bytes are equivalent.
|
||||
assertEquals(generatedMessage.toByteString(), bytes);
|
||||
}
|
||||
|
||||
public void testReflectionEqualsAndHashCode() throws Exception {
|
||||
// Test that generated equals() and hashCode() will disregard the order
|
||||
// of map entries when comparing/hashing map fields.
|
||||
|
@ -893,6 +893,24 @@ public class MapTest extends TestCase {
|
||||
assertEquals(message.hashCode(), dynamicMessage.hashCode());
|
||||
}
|
||||
|
||||
// Check that DynamicMessage handles map field serialization the same way as generated code
|
||||
// regarding unset key and value field in a map entry.
|
||||
public void testDynamicMessageUnsetKeyAndValue() throws Exception {
|
||||
FieldDescriptor field = f("int32_to_int32_field");
|
||||
|
||||
Message dynamicDefaultInstance =
|
||||
DynamicMessage.getDefaultInstance(TestMap.getDescriptor());
|
||||
Message.Builder builder = dynamicDefaultInstance.newBuilderForType();
|
||||
// Add an entry without key and value.
|
||||
builder.addRepeatedField(field, builder.newBuilderForField(field).build());
|
||||
Message message = builder.build();
|
||||
ByteString bytes = message.toByteString();
|
||||
// Parse it back to the same generated type.
|
||||
Message generatedMessage = TestMap.parseFrom(bytes);
|
||||
// Assert the serialized bytes are equivalent.
|
||||
assertEquals(generatedMessage.toByteString(), bytes);
|
||||
}
|
||||
|
||||
public void testReflectionEqualsAndHashCode() throws Exception {
|
||||
// Test that generated equals() and hashCode() will disregard the order
|
||||
// of map entries when comparing/hashing map fields.
|
||||
|
@ -61,12 +61,11 @@ import junit.framework.TestCase;
|
||||
public class TextFormatTest extends TestCase {
|
||||
|
||||
// A basic string with different escapable characters for testing.
|
||||
private final static String kEscapeTestString =
|
||||
"\"A string with ' characters \n and \r newlines and \t tabs and \001 "
|
||||
+ "slashes \\";
|
||||
private static final String ESCAPE_TEST_STRING =
|
||||
"\"A string with ' characters \n and \r newlines and \t tabs and \001 " + "slashes \\";
|
||||
|
||||
// A representation of the above string with all the characters escaped.
|
||||
private final static String kEscapeTestStringEscaped =
|
||||
private static final String ESCAPE_TEST_STRING_ESCAPED =
|
||||
"\\\"A string with \\' characters \\n and \\r newlines "
|
||||
+ "and \\t tabs and \\001 slashes \\\\";
|
||||
|
||||
@ -576,10 +575,10 @@ public class TextFormatTest extends TestCase {
|
||||
"integer: 82301481290849012385230157",
|
||||
"optional_int32: 82301481290849012385230157");
|
||||
assertParseError(
|
||||
"1:16: Expected \"true\" or \"false\".",
|
||||
"1:16: Expected \"true\" or \"false\". Found \"maybe\".",
|
||||
"optional_bool: maybe");
|
||||
assertParseError(
|
||||
"1:16: Expected \"true\" or \"false\".",
|
||||
"1:16: Expected \"true\" or \"false\". Found \"2\".",
|
||||
"optional_bool: 2");
|
||||
assertParseError(
|
||||
"1:18: Expected string.",
|
||||
@ -643,10 +642,8 @@ public class TextFormatTest extends TestCase {
|
||||
TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
|
||||
assertEquals("\0\001\007\b\f\n\r\t\013\\\'\"",
|
||||
TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
|
||||
assertEquals(kEscapeTestStringEscaped,
|
||||
TextFormat.escapeText(kEscapeTestString));
|
||||
assertEquals(kEscapeTestString,
|
||||
TextFormat.unescapeText(kEscapeTestStringEscaped));
|
||||
assertEquals(ESCAPE_TEST_STRING_ESCAPED, TextFormat.escapeText(ESCAPE_TEST_STRING));
|
||||
assertEquals(ESCAPE_TEST_STRING, TextFormat.unescapeText(ESCAPE_TEST_STRING_ESCAPED));
|
||||
|
||||
// Invariant
|
||||
assertEquals("hello",
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
|
||||
import com.google.protobuf.UnittestLite.TestAllTypesLite;
|
||||
import protobuf_unittest.UnittestProto;
|
||||
@ -133,6 +135,25 @@ public class UnknownFieldSetLiteTest extends TestCase {
|
||||
assertEquals(foo.toByteString().size(), instance.getSerializedSize());
|
||||
}
|
||||
|
||||
public void testHashCodeAfterDeserialization() throws IOException {
|
||||
Foo foo = Foo.newBuilder()
|
||||
.setValue(2)
|
||||
.build();
|
||||
|
||||
Foo fooDeserialized = Foo.parseFrom(foo.toByteArray());
|
||||
|
||||
assertEquals(fooDeserialized, foo);
|
||||
assertEquals(foo.hashCode(), fooDeserialized.hashCode());
|
||||
}
|
||||
|
||||
public void testNewInstanceHashCode() {
|
||||
UnknownFieldSetLite emptyFieldSet = UnknownFieldSetLite.getDefaultInstance();
|
||||
UnknownFieldSetLite paddedFieldSet = UnknownFieldSetLite.newInstance();
|
||||
|
||||
assertEquals(emptyFieldSet, paddedFieldSet);
|
||||
assertEquals(emptyFieldSet.hashCode(), paddedFieldSet.hashCode());
|
||||
}
|
||||
|
||||
public void testMergeVarintField() throws IOException {
|
||||
UnknownFieldSetLite unknownFields = UnknownFieldSetLite.newInstance();
|
||||
unknownFields.mergeVarintField(10, 2);
|
||||
|
@ -36,6 +36,7 @@ import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
|
||||
import protobuf_unittest.UnittestProto;
|
||||
import protobuf_unittest.UnittestProto.TestAllExtensions;
|
||||
import protobuf_unittest.UnittestProto.TestAllTypes;
|
||||
import protobuf_unittest.UnittestProto.TestExtensionInsideTable;
|
||||
import protobuf_unittest.UnittestProto.TestFieldOrderings;
|
||||
import protobuf_unittest.UnittestProto.TestOneof2;
|
||||
import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
|
||||
@ -235,6 +236,26 @@ public class WireFormatTest extends TestCase {
|
||||
getTestFieldOrderingsRegistry());
|
||||
assertEquals(source, dest);
|
||||
}
|
||||
|
||||
private static ExtensionRegistry getTestExtensionInsideTableRegistry() {
|
||||
ExtensionRegistry result = ExtensionRegistry.newInstance();
|
||||
result.add(UnittestProto.testExtensionInsideTableExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void testExtensionInsideTable() throws Exception {
|
||||
// Make sure the extension within the range of table is parsed correctly in experimental
|
||||
// runtime.
|
||||
TestExtensionInsideTable source =
|
||||
TestExtensionInsideTable.newBuilder()
|
||||
.setField1(1)
|
||||
.setExtension(UnittestProto.testExtensionInsideTableExtension, 23)
|
||||
.build();
|
||||
TestExtensionInsideTable dest =
|
||||
TestExtensionInsideTable.parseFrom(source.toByteString(),
|
||||
getTestExtensionInsideTableRegistry());
|
||||
assertEquals(source, dest);
|
||||
}
|
||||
|
||||
public void testParseMultipleExtensionRangesDynamic() throws Exception {
|
||||
// Same as above except with DynamicMessage.
|
||||
|
@ -60,14 +60,25 @@ goog.forwardDeclare('jsproto.BinaryExtension');
|
||||
|
||||
|
||||
/**
|
||||
* Base interface class for all const messages. Does __not__ define any
|
||||
* methods, as doing so on a widely-used interface defeats dead-code
|
||||
* elimination.
|
||||
* Base interface class for all const messages.
|
||||
* @interface
|
||||
*/
|
||||
jspb.ConstBinaryMessage = function() {};
|
||||
|
||||
/**
|
||||
* Generate a debug string for this proto that is in proto2 text format.
|
||||
* @return {string} The debug string.
|
||||
*/
|
||||
jspb.ConstBinaryMessage.prototype.toDebugString;
|
||||
|
||||
/**
|
||||
* Helper to generate a debug string for this proto at some indent level. The
|
||||
* first line is not indented.
|
||||
* @param {number} indentLevel The number of spaces by which to indent lines.
|
||||
* @return {string} The debug string.
|
||||
* @protected
|
||||
*/
|
||||
jspb.ConstBinaryMessage.prototype.toDebugStringInternal;
|
||||
|
||||
/**
|
||||
* Base interface class for all messages. Does __not__ define any methods, as
|
||||
@ -97,6 +108,7 @@ jspb.ScalarFieldType;
|
||||
* A repeated field in jspb is an array of scalars, blobs, or messages.
|
||||
* @typedef {!Array<jspb.ScalarFieldType>|
|
||||
!Array<!Uint8Array>|
|
||||
!Array<!jspb.ConstBinaryMessage>|
|
||||
!Array<!jspb.BinaryMessage>}
|
||||
*/
|
||||
jspb.RepeatedFieldType;
|
||||
@ -108,6 +120,7 @@ jspb.RepeatedFieldType;
|
||||
* @typedef {jspb.ScalarFieldType|
|
||||
jspb.RepeatedFieldType|
|
||||
!Uint8Array|
|
||||
!jspb.ConstBinaryMessage|
|
||||
!jspb.BinaryMessage|
|
||||
!jsproto.BinaryExtension}
|
||||
*/
|
||||
|
@ -986,7 +986,7 @@ jspb.BinaryDecoder.prototype.readString = function(length) {
|
||||
codeUnits.push(high, low);
|
||||
}
|
||||
|
||||
// Avoid exceeding the maximum stack size when calling {@code apply}.
|
||||
// Avoid exceeding the maximum stack size when calling `apply`.
|
||||
if (codeUnits.length >= 8192) {
|
||||
result += String.fromCharCode.apply(null, codeUnits);
|
||||
codeUnits.length = 0;
|
||||
|
@ -236,10 +236,12 @@ jspb.BinaryWriter.prototype.getResultBuffer = function() {
|
||||
|
||||
/**
|
||||
* Converts the encoded data into a base64-encoded string.
|
||||
* @param {boolean=} opt_webSafe True indicates we should use a websafe
|
||||
* alphabet, which does not require escaping for use in URLs.
|
||||
* @return {string}
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.getResultBase64String = function() {
|
||||
return goog.crypt.base64.encodeByteArray(this.getResultBuffer());
|
||||
jspb.BinaryWriter.prototype.getResultBase64String = function(opt_webSafe) {
|
||||
return goog.crypt.base64.encodeByteArray(this.getResultBuffer(), opt_webSafe);
|
||||
};
|
||||
|
||||
|
||||
|
@ -118,4 +118,16 @@ describe('binaryWriterTest', function() {
|
||||
var buffer = writer.getResultBuffer();
|
||||
assertEquals(expected, goog.crypt.byteArrayToHex(buffer));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests websafe encodings for base64 strings.
|
||||
*/
|
||||
it('testWebSafeOption', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeBytes(1, new Uint8Array([127]));
|
||||
assertEquals('CgF/', writer.getResultBase64String());
|
||||
assertEquals('CgF/', writer.getResultBase64String(false));
|
||||
assertEquals('CgF_', writer.getResultBase64String(true));
|
||||
});
|
||||
});
|
||||
|
@ -42,7 +42,7 @@ goog.require('jspb.Message');
|
||||
|
||||
/**
|
||||
* Turns a proto into a human readable object that can i.e. be written to the
|
||||
* console: {@code console.log(jspb.debug.dump(myProto))}.
|
||||
* console: `console.log(jspb.debug.dump(myProto))`.
|
||||
* This function makes a best effort and may not work in all cases. It will not
|
||||
* work in obfuscated and or optimized code.
|
||||
* Use this in environments where {@see jspb.Message.prototype.toObject} is
|
||||
|
16
js/map.js
16
js/map.js
@ -48,9 +48,9 @@ goog.forwardDeclare('jspb.BinaryWriter');
|
||||
*
|
||||
* @template K, V
|
||||
*
|
||||
* @param {!Array<!Array<!Object>>} arr
|
||||
* @param {!Array<!Array<?>>} arr
|
||||
*
|
||||
* @param {?function(new:V)|function(new:V,?)=} opt_valueCtor
|
||||
* @param {?function(new:V, ?=)=} opt_valueCtor
|
||||
* The constructor for type V, if type V is a message type.
|
||||
*
|
||||
* @constructor
|
||||
@ -118,7 +118,7 @@ jspb.Map.prototype.toArray = function() {
|
||||
strKeys.sort();
|
||||
for (var i = 0; i < strKeys.length; i++) {
|
||||
var entry = this.map_[strKeys[i]];
|
||||
var valueWrapper = /** @type {!Object} */ (entry.valueWrapper);
|
||||
var valueWrapper = /** @type {?jspb.Message} */ (entry.valueWrapper);
|
||||
if (valueWrapper) {
|
||||
valueWrapper.toArray();
|
||||
}
|
||||
@ -165,7 +165,7 @@ jspb.Map.prototype.toObject = function(includeInstance, valueToObject) {
|
||||
*
|
||||
* @template K, V
|
||||
* @param {!Array<!Array<!Object>>} entries
|
||||
* @param {!function(new:V)|function(new:V,?)} valueCtor
|
||||
* @param {!function(new:V,?=)} valueCtor
|
||||
* The constructor for type V.
|
||||
* @param {!function(!Object):V} valueFromObject
|
||||
* The fromObject function for type V.
|
||||
@ -432,7 +432,8 @@ jspb.Map.prototype.serializeBinary = function(
|
||||
valueWriterFn.call(writer, 2, this.wrapEntry_(entry),
|
||||
opt_valueWriterCallback);
|
||||
} else {
|
||||
valueWriterFn.call(writer, 2, entry.value);
|
||||
/** @type {function(this:jspb.BinaryWriter,number,?)} */ (valueWriterFn)
|
||||
.call(writer, 2, entry.value);
|
||||
}
|
||||
writer.endSubMessage();
|
||||
}
|
||||
@ -475,10 +476,13 @@ jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn,
|
||||
} else if (field == 2) {
|
||||
// Value.
|
||||
if (map.valueCtor_) {
|
||||
goog.asserts.assert(opt_valueReaderCallback);
|
||||
value = new map.valueCtor_();
|
||||
valueReaderFn.call(reader, value, opt_valueReaderCallback);
|
||||
} else {
|
||||
value = valueReaderFn.call(reader);
|
||||
value =
|
||||
(/** @type {function(this:jspb.BinaryReader):?} */ (valueReaderFn))
|
||||
.call(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,17 +215,6 @@ goog.define('jspb.Message.ASSUME_LOCAL_ARRAYS', false);
|
||||
goog.define('jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS', true);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Turning on this flag does NOT change the behavior of JSPB
|
||||
* and only affects private internal state. It may, however, break some
|
||||
* tests that use naive deeply-equals algorithms, because using a proto
|
||||
* mutates its internal state.
|
||||
* Projects are advised to turn this flag always on.
|
||||
*/
|
||||
goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', true);
|
||||
// TODO(b/19419436): Delete this flag.
|
||||
|
||||
|
||||
/**
|
||||
* Does this JavaScript environment support Uint8Aray typed arrays?
|
||||
* @type {boolean}
|
||||
@ -369,7 +358,7 @@ jspb.Message.getFieldNumber_ = function(msg, index) {
|
||||
*/
|
||||
jspb.Message.initialize = function(
|
||||
msg, data, messageId, suggestedPivot, repeatedFields, opt_oneofFields) {
|
||||
msg.wrappers_ = jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ? null : {};
|
||||
msg.wrappers_ = null;
|
||||
if (!data) {
|
||||
data = messageId ? [messageId] : [];
|
||||
}
|
||||
@ -394,17 +383,12 @@ jspb.Message.initialize = function(
|
||||
var fieldNumber = repeatedFields[i];
|
||||
if (fieldNumber < msg.pivot_) {
|
||||
var index = jspb.Message.getIndex_(msg, fieldNumber);
|
||||
msg.array[index] = msg.array[index] ||
|
||||
(jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
|
||||
jspb.Message.EMPTY_LIST_SENTINEL_ :
|
||||
[]);
|
||||
msg.array[index] =
|
||||
msg.array[index] || jspb.Message.EMPTY_LIST_SENTINEL_;
|
||||
} else {
|
||||
jspb.Message.maybeInitEmptyExtensionObject_(msg);
|
||||
msg.extensionObject_[fieldNumber] =
|
||||
msg.extensionObject_[fieldNumber] ||
|
||||
(jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
|
||||
jspb.Message.EMPTY_LIST_SENTINEL_ :
|
||||
[]);
|
||||
msg.extensionObject_[fieldNumber] = msg.extensionObject_[fieldNumber] ||
|
||||
jspb.Message.EMPTY_LIST_SENTINEL_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -517,8 +501,7 @@ jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) {
|
||||
// And not using it here to avoid a function call.
|
||||
var result = [];
|
||||
for (var i = 0; i < field.length; i++) {
|
||||
result[i] = toObjectFn.call(field[i], opt_includeInstance,
|
||||
/** @type {!jspb.Message} */ (field[i]));
|
||||
result[i] = toObjectFn.call(field[i], opt_includeInstance, field[i]);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
@ -551,10 +534,11 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions,
|
||||
} else {
|
||||
if (fieldInfo.isRepeated) {
|
||||
obj[name] = jspb.Message.toObjectList(
|
||||
/** @type {!Array<jspb.Message>} */ (value),
|
||||
/** @type {!Array<!jspb.Message>} */ (value),
|
||||
fieldInfo.toObjectFn, opt_includeInstance);
|
||||
} else {
|
||||
obj[name] = fieldInfo.toObjectFn(opt_includeInstance, value);
|
||||
obj[name] = fieldInfo.toObjectFn(
|
||||
opt_includeInstance, /** @type {!jspb.Message} */ (value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1419,7 +1403,7 @@ jspb.Message.prototype.setExtension = function(fieldInfo, value) {
|
||||
if (fieldInfo.isMessageType()) {
|
||||
self.wrappers_[fieldNumber] = value;
|
||||
self.extensionObject_[fieldNumber] = goog.array.map(
|
||||
/** @type {Array<jspb.Message>} */ (value), function(msg) {
|
||||
/** @type {!Array<!jspb.Message>} */ (value), function(msg) {
|
||||
return msg.toArray();
|
||||
});
|
||||
} else {
|
||||
@ -1428,7 +1412,8 @@ jspb.Message.prototype.setExtension = function(fieldInfo, value) {
|
||||
} else {
|
||||
if (fieldInfo.isMessageType()) {
|
||||
self.wrappers_[fieldNumber] = value;
|
||||
self.extensionObject_[fieldNumber] = value ? value.toArray() : value;
|
||||
self.extensionObject_[fieldNumber] =
|
||||
value ? /** @type {!jspb.Message} */ (value).toArray() : value;
|
||||
} else {
|
||||
self.extensionObject_[fieldNumber] = value;
|
||||
}
|
||||
@ -1530,9 +1515,15 @@ jspb.Message.compareFields = function(field1, field2) {
|
||||
// If the fields are trivially equal, they're equal.
|
||||
if (field1 == field2) return true;
|
||||
|
||||
// If the fields aren't trivially equal and one of them isn't an object,
|
||||
// they can't possibly be equal.
|
||||
if (!goog.isObject(field1) || !goog.isObject(field2)) {
|
||||
// NaN != NaN so we cover this case.
|
||||
if ((goog.isNumber(field1) && isNaN(field1)) ||
|
||||
(goog.isNumber(field2) && isNaN(field2))) {
|
||||
// One of the fields might be a string 'NaN'.
|
||||
return String(field1) == String(field2);
|
||||
}
|
||||
// If the fields aren't trivially equal and one of them isn't an object,
|
||||
// they can't possibly be equal.
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1555,24 +1546,26 @@ jspb.Message.compareFields = function(field1, field2) {
|
||||
// If they're both Arrays, compare them element by element except for the
|
||||
// optional extension objects at the end, which we compare separately.
|
||||
if (field1.constructor === Array) {
|
||||
var typedField1 = /** @type {!Array<?>} */ (field1);
|
||||
var typedField2 = /** @type {!Array<?>} */ (field2);
|
||||
var extension1 = undefined;
|
||||
var extension2 = undefined;
|
||||
|
||||
var length = Math.max(field1.length, field2.length);
|
||||
var length = Math.max(typedField1.length, typedField2.length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var val1 = field1[i];
|
||||
var val2 = field2[i];
|
||||
var val1 = typedField1[i];
|
||||
var val2 = typedField2[i];
|
||||
|
||||
if (val1 && (val1.constructor == Object)) {
|
||||
goog.asserts.assert(extension1 === undefined);
|
||||
goog.asserts.assert(i === field1.length - 1);
|
||||
goog.asserts.assert(i === typedField1.length - 1);
|
||||
extension1 = val1;
|
||||
val1 = undefined;
|
||||
}
|
||||
|
||||
if (val2 && (val2.constructor == Object)) {
|
||||
goog.asserts.assert(extension2 === undefined);
|
||||
goog.asserts.assert(i === field2.length - 1);
|
||||
goog.asserts.assert(i === typedField2.length - 1);
|
||||
extension2 = val2;
|
||||
val2 = undefined;
|
||||
}
|
||||
@ -1695,8 +1688,13 @@ jspb.Message.clone_ = function(obj) {
|
||||
var clonedArray = new Array(obj.length);
|
||||
// Use array iteration where possible because it is faster than for-in.
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
if ((o = obj[i]) != null) {
|
||||
clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
|
||||
o = obj[i];
|
||||
if (o != null) {
|
||||
// NOTE:redundant null check existing for NTI compatibility.
|
||||
// see b/70515949
|
||||
clonedArray[i] = (typeof o == 'object') ?
|
||||
jspb.Message.clone_(goog.asserts.assert(o)) :
|
||||
o;
|
||||
}
|
||||
}
|
||||
return clonedArray;
|
||||
@ -1706,8 +1704,13 @@ jspb.Message.clone_ = function(obj) {
|
||||
}
|
||||
var clone = {};
|
||||
for (var key in obj) {
|
||||
if ((o = obj[key]) != null) {
|
||||
clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
|
||||
o = obj[key];
|
||||
if (o != null) {
|
||||
// NOTE:redundant null check existing for NTI compatibility.
|
||||
// see b/70515949
|
||||
clone[key] = (typeof o == 'object') ?
|
||||
jspb.Message.clone_(goog.asserts.assert(o)) :
|
||||
o;
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
@ -1723,6 +1726,9 @@ jspb.Message.registerMessageType = function(id, constructor) {
|
||||
jspb.Message.registry_[id] = constructor;
|
||||
// This is needed so we can later access messageId directly on the contructor,
|
||||
// otherwise it is not available due to 'property collapsing' by the compiler.
|
||||
/**
|
||||
* @suppress {strictMissingProperties} messageId is not defined on Function
|
||||
*/
|
||||
constructor.messageId = id;
|
||||
};
|
||||
|
||||
|
@ -418,6 +418,18 @@ describe('Message test suite', function() {
|
||||
['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
|
||||
});
|
||||
|
||||
it('testEqualsNonFinite', function() {
|
||||
assertTrue(jspb.Message.compareFields(NaN, NaN));
|
||||
assertTrue(jspb.Message.compareFields(NaN, 'NaN'));
|
||||
assertTrue(jspb.Message.compareFields('NaN', NaN));
|
||||
assertTrue(jspb.Message.compareFields(Infinity, Infinity));
|
||||
assertTrue(jspb.Message.compareFields(Infinity, 'Infinity'));
|
||||
assertTrue(jspb.Message.compareFields('-Infinity', -Infinity));
|
||||
assertTrue(jspb.Message.compareFields([NaN], ['NaN']));
|
||||
assertFalse(jspb.Message.compareFields(undefined, NaN));
|
||||
assertFalse(jspb.Message.compareFields(NaN, undefined));
|
||||
});
|
||||
|
||||
it('testToMap', function() {
|
||||
var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
|
||||
var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
|
||||
|
@ -34,6 +34,7 @@ file, in types that make this information accessible in Python.
|
||||
|
||||
__author__ = 'robinson@google.com (Will Robinson)'
|
||||
|
||||
import threading
|
||||
import six
|
||||
|
||||
from google.protobuf.internal import api_implementation
|
||||
@ -72,6 +73,24 @@ else:
|
||||
DescriptorMetaclass = type
|
||||
|
||||
|
||||
class _Lock(object):
|
||||
"""Wrapper class of threading.Lock(), which is allowed by 'with'."""
|
||||
|
||||
def __new__(cls):
|
||||
self = object.__new__(cls)
|
||||
self._lock = threading.Lock() # pylint: disable=protected-access
|
||||
return self
|
||||
|
||||
def __enter__(self):
|
||||
self._lock.acquire()
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||
self._lock.release()
|
||||
|
||||
|
||||
_lock = threading.Lock()
|
||||
|
||||
|
||||
class DescriptorBase(six.with_metaclass(DescriptorMetaclass)):
|
||||
|
||||
"""Descriptors base class.
|
||||
@ -92,16 +111,17 @@ class DescriptorBase(six.with_metaclass(DescriptorMetaclass)):
|
||||
# subclasses" of this descriptor class.
|
||||
_C_DESCRIPTOR_CLASS = ()
|
||||
|
||||
def __init__(self, options, options_class_name):
|
||||
def __init__(self, options, serialized_options, options_class_name):
|
||||
"""Initialize the descriptor given its options message and the name of the
|
||||
class of the options message. The name of the class is required in case
|
||||
the options message is None and has to be created.
|
||||
"""
|
||||
self._options = options
|
||||
self._options_class_name = options_class_name
|
||||
self._serialized_options = serialized_options
|
||||
|
||||
# Does this descriptor have non-default options?
|
||||
self.has_options = options is not None
|
||||
self.has_options = (options is not None) or (serialized_options is not None)
|
||||
|
||||
def _SetOptions(self, options, options_class_name):
|
||||
"""Sets the descriptor's options
|
||||
@ -123,14 +143,23 @@ class DescriptorBase(six.with_metaclass(DescriptorMetaclass)):
|
||||
"""
|
||||
if self._options:
|
||||
return self._options
|
||||
|
||||
from google.protobuf import descriptor_pb2
|
||||
try:
|
||||
options_class = getattr(descriptor_pb2, self._options_class_name)
|
||||
options_class = getattr(descriptor_pb2,
|
||||
self._options_class_name)
|
||||
except AttributeError:
|
||||
raise RuntimeError('Unknown options class name %s!' %
|
||||
(self._options_class_name))
|
||||
self._options = options_class()
|
||||
return self._options
|
||||
|
||||
with _lock:
|
||||
if self._serialized_options is None:
|
||||
self._options = options_class()
|
||||
else:
|
||||
self._options = _ParseOptions(options_class(),
|
||||
self._serialized_options)
|
||||
|
||||
return self._options
|
||||
|
||||
|
||||
class _NestedDescriptorBase(DescriptorBase):
|
||||
@ -138,7 +167,7 @@ class _NestedDescriptorBase(DescriptorBase):
|
||||
|
||||
def __init__(self, options, options_class_name, name, full_name,
|
||||
file, containing_type, serialized_start=None,
|
||||
serialized_end=None):
|
||||
serialized_end=None, serialized_options=None):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
@ -157,9 +186,10 @@ class _NestedDescriptorBase(DescriptorBase):
|
||||
file.serialized_pb that describes this descriptor.
|
||||
serialized_end: The end index (exclusive) in block in the
|
||||
file.serialized_pb that describes this descriptor.
|
||||
serialized_options: Protocol message serilized options or None.
|
||||
"""
|
||||
super(_NestedDescriptorBase, self).__init__(
|
||||
options, options_class_name)
|
||||
options, serialized_options, options_class_name)
|
||||
|
||||
self.name = name
|
||||
# TODO(falk): Add function to calculate full_name instead of having it in
|
||||
@ -250,6 +280,7 @@ class Descriptor(_NestedDescriptorBase):
|
||||
|
||||
def __new__(cls, name, full_name, filename, containing_type, fields,
|
||||
nested_types, enum_types, extensions, options=None,
|
||||
serialized_options=None,
|
||||
is_extendable=True, extension_ranges=None, oneofs=None,
|
||||
file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin
|
||||
syntax=None):
|
||||
@ -261,6 +292,7 @@ class Descriptor(_NestedDescriptorBase):
|
||||
# name of the argument.
|
||||
def __init__(self, name, full_name, filename, containing_type, fields,
|
||||
nested_types, enum_types, extensions, options=None,
|
||||
serialized_options=None,
|
||||
is_extendable=True, extension_ranges=None, oneofs=None,
|
||||
file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin
|
||||
syntax=None):
|
||||
@ -273,7 +305,7 @@ class Descriptor(_NestedDescriptorBase):
|
||||
super(Descriptor, self).__init__(
|
||||
options, 'MessageOptions', name, full_name, file,
|
||||
containing_type, serialized_start=serialized_start,
|
||||
serialized_end=serialized_end)
|
||||
serialized_end=serialized_end, serialized_options=serialized_options)
|
||||
|
||||
# We have fields in addition to fields_by_name and fields_by_number,
|
||||
# so that:
|
||||
@ -492,8 +524,9 @@ class FieldDescriptor(DescriptorBase):
|
||||
def __new__(cls, name, full_name, index, number, type, cpp_type, label,
|
||||
default_value, message_type, enum_type, containing_type,
|
||||
is_extension, extension_scope, options=None,
|
||||
serialized_options=None,
|
||||
has_default_value=True, containing_oneof=None, json_name=None,
|
||||
file=None):
|
||||
file=None): # pylint: disable=redefined-builtin
|
||||
_message.Message._CheckCalledFromGeneratedFile()
|
||||
if is_extension:
|
||||
return _message.default_pool.FindExtensionByName(full_name)
|
||||
@ -503,8 +536,9 @@ class FieldDescriptor(DescriptorBase):
|
||||
def __init__(self, name, full_name, index, number, type, cpp_type, label,
|
||||
default_value, message_type, enum_type, containing_type,
|
||||
is_extension, extension_scope, options=None,
|
||||
serialized_options=None,
|
||||
has_default_value=True, containing_oneof=None, json_name=None,
|
||||
file=None):
|
||||
file=None): # pylint: disable=redefined-builtin
|
||||
"""The arguments are as described in the description of FieldDescriptor
|
||||
attributes above.
|
||||
|
||||
@ -512,7 +546,8 @@ class FieldDescriptor(DescriptorBase):
|
||||
(to deal with circular references between message types, for example).
|
||||
Likewise for extension_scope.
|
||||
"""
|
||||
super(FieldDescriptor, self).__init__(options, 'FieldOptions')
|
||||
super(FieldDescriptor, self).__init__(
|
||||
options, serialized_options, 'FieldOptions')
|
||||
self.name = name
|
||||
self.full_name = full_name
|
||||
self.file = file
|
||||
@ -598,13 +633,15 @@ class EnumDescriptor(_NestedDescriptorBase):
|
||||
_C_DESCRIPTOR_CLASS = _message.EnumDescriptor
|
||||
|
||||
def __new__(cls, name, full_name, filename, values,
|
||||
containing_type=None, options=None, file=None,
|
||||
containing_type=None, options=None,
|
||||
serialized_options=None, file=None, # pylint: disable=redefined-builtin
|
||||
serialized_start=None, serialized_end=None):
|
||||
_message.Message._CheckCalledFromGeneratedFile()
|
||||
return _message.default_pool.FindEnumTypeByName(full_name)
|
||||
|
||||
def __init__(self, name, full_name, filename, values,
|
||||
containing_type=None, options=None, file=None,
|
||||
containing_type=None, options=None,
|
||||
serialized_options=None, file=None, # pylint: disable=redefined-builtin
|
||||
serialized_start=None, serialized_end=None):
|
||||
"""Arguments are as described in the attribute description above.
|
||||
|
||||
@ -614,7 +651,7 @@ class EnumDescriptor(_NestedDescriptorBase):
|
||||
super(EnumDescriptor, self).__init__(
|
||||
options, 'EnumOptions', name, full_name, file,
|
||||
containing_type, serialized_start=serialized_start,
|
||||
serialized_end=serialized_end)
|
||||
serialized_end=serialized_end, serialized_options=serialized_options)
|
||||
|
||||
self.values = values
|
||||
for value in self.values:
|
||||
@ -650,7 +687,9 @@ class EnumValueDescriptor(DescriptorBase):
|
||||
if _USE_C_DESCRIPTORS:
|
||||
_C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor
|
||||
|
||||
def __new__(cls, name, index, number, type=None, options=None):
|
||||
def __new__(cls, name, index, number,
|
||||
type=None, # pylint: disable=redefined-builtin
|
||||
options=None, serialized_options=None):
|
||||
_message.Message._CheckCalledFromGeneratedFile()
|
||||
# There is no way we can build a complete EnumValueDescriptor with the
|
||||
# given parameters (the name of the Enum is not known, for example).
|
||||
@ -658,9 +697,12 @@ class EnumValueDescriptor(DescriptorBase):
|
||||
# constructor, which will ignore it, so returning None is good enough.
|
||||
return None
|
||||
|
||||
def __init__(self, name, index, number, type=None, options=None):
|
||||
def __init__(self, name, index, number,
|
||||
type=None, # pylint: disable=redefined-builtin
|
||||
options=None, serialized_options=None):
|
||||
"""Arguments are as described in the attribute description above."""
|
||||
super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
|
||||
super(EnumValueDescriptor, self).__init__(
|
||||
options, serialized_options, 'EnumValueOptions')
|
||||
self.name = name
|
||||
self.index = index
|
||||
self.number = number
|
||||
@ -685,14 +727,17 @@ class OneofDescriptor(DescriptorBase):
|
||||
_C_DESCRIPTOR_CLASS = _message.OneofDescriptor
|
||||
|
||||
def __new__(
|
||||
cls, name, full_name, index, containing_type, fields, options=None):
|
||||
cls, name, full_name, index, containing_type, fields, options=None,
|
||||
serialized_options=None):
|
||||
_message.Message._CheckCalledFromGeneratedFile()
|
||||
return _message.default_pool.FindOneofByName(full_name)
|
||||
|
||||
def __init__(
|
||||
self, name, full_name, index, containing_type, fields, options=None):
|
||||
self, name, full_name, index, containing_type, fields, options=None,
|
||||
serialized_options=None):
|
||||
"""Arguments are as described in the attribute description above."""
|
||||
super(OneofDescriptor, self).__init__(options, 'OneofOptions')
|
||||
super(OneofDescriptor, self).__init__(
|
||||
options, serialized_options, 'OneofOptions')
|
||||
self.name = name
|
||||
self.full_name = full_name
|
||||
self.index = index
|
||||
@ -721,17 +766,19 @@ class ServiceDescriptor(_NestedDescriptorBase):
|
||||
if _USE_C_DESCRIPTORS:
|
||||
_C_DESCRIPTOR_CLASS = _message.ServiceDescriptor
|
||||
|
||||
def __new__(cls, name, full_name, index, methods, options=None, file=None, # pylint: disable=redefined-builtin
|
||||
def __new__(cls, name, full_name, index, methods, options=None,
|
||||
serialized_options=None, file=None, # pylint: disable=redefined-builtin
|
||||
serialized_start=None, serialized_end=None):
|
||||
_message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access
|
||||
return _message.default_pool.FindServiceByName(full_name)
|
||||
|
||||
def __init__(self, name, full_name, index, methods, options=None, file=None,
|
||||
def __init__(self, name, full_name, index, methods, options=None,
|
||||
serialized_options=None, file=None, # pylint: disable=redefined-builtin
|
||||
serialized_start=None, serialized_end=None):
|
||||
super(ServiceDescriptor, self).__init__(
|
||||
options, 'ServiceOptions', name, full_name, file,
|
||||
None, serialized_start=serialized_start,
|
||||
serialized_end=serialized_end)
|
||||
serialized_end=serialized_end, serialized_options=serialized_options)
|
||||
self.index = index
|
||||
self.methods = methods
|
||||
self.methods_by_name = dict((m.name, m) for m in methods)
|
||||
@ -772,18 +819,19 @@ class MethodDescriptor(DescriptorBase):
|
||||
_C_DESCRIPTOR_CLASS = _message.MethodDescriptor
|
||||
|
||||
def __new__(cls, name, full_name, index, containing_service,
|
||||
input_type, output_type, options=None):
|
||||
input_type, output_type, options=None, serialized_options=None):
|
||||
_message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access
|
||||
return _message.default_pool.FindMethodByName(full_name)
|
||||
|
||||
def __init__(self, name, full_name, index, containing_service,
|
||||
input_type, output_type, options=None):
|
||||
input_type, output_type, options=None, serialized_options=None):
|
||||
"""The arguments are as described in the description of MethodDescriptor
|
||||
attributes above.
|
||||
|
||||
Note that containing_service may be None, and may be set later if necessary.
|
||||
"""
|
||||
super(MethodDescriptor, self).__init__(options, 'MethodOptions')
|
||||
super(MethodDescriptor, self).__init__(
|
||||
options, serialized_options, 'MethodOptions')
|
||||
self.name = name
|
||||
self.full_name = full_name
|
||||
self.index = index
|
||||
@ -818,7 +866,8 @@ class FileDescriptor(DescriptorBase):
|
||||
if _USE_C_DESCRIPTORS:
|
||||
_C_DESCRIPTOR_CLASS = _message.FileDescriptor
|
||||
|
||||
def __new__(cls, name, package, options=None, serialized_pb=None,
|
||||
def __new__(cls, name, package, options=None,
|
||||
serialized_options=None, serialized_pb=None,
|
||||
dependencies=None, public_dependencies=None,
|
||||
syntax=None, pool=None):
|
||||
# FileDescriptor() is called from various places, not only from generated
|
||||
@ -830,11 +879,13 @@ class FileDescriptor(DescriptorBase):
|
||||
else:
|
||||
return super(FileDescriptor, cls).__new__(cls)
|
||||
|
||||
def __init__(self, name, package, options=None, serialized_pb=None,
|
||||
def __init__(self, name, package, options=None,
|
||||
serialized_options=None, serialized_pb=None,
|
||||
dependencies=None, public_dependencies=None,
|
||||
syntax=None, pool=None):
|
||||
"""Constructor."""
|
||||
super(FileDescriptor, self).__init__(options, 'FileOptions')
|
||||
super(FileDescriptor, self).__init__(
|
||||
options, serialized_options, 'FileOptions')
|
||||
|
||||
if pool is None:
|
||||
from google.protobuf import descriptor_pool
|
||||
|
@ -37,8 +37,8 @@ argument tuples.
|
||||
|
||||
A simple example:
|
||||
|
||||
class AdditionExample(parameterized.ParameterizedTestCase):
|
||||
@parameterized.Parameters(
|
||||
class AdditionExample(parameterized.TestCase):
|
||||
@parameterized.parameters(
|
||||
(1, 2, 3),
|
||||
(4, 5, 9),
|
||||
(1, 1, 3))
|
||||
@ -54,8 +54,8 @@ fail due to an assertion error (1 + 1 != 3).
|
||||
Parameters for invididual test cases can be tuples (with positional parameters)
|
||||
or dictionaries (with named parameters):
|
||||
|
||||
class AdditionExample(parameterized.ParameterizedTestCase):
|
||||
@parameterized.Parameters(
|
||||
class AdditionExample(parameterized.TestCase):
|
||||
@parameterized.parameters(
|
||||
{'op1': 1, 'op2': 2, 'result': 3},
|
||||
{'op1': 4, 'op2': 5, 'result': 9},
|
||||
)
|
||||
@ -77,13 +77,13 @@ stay the same across several invocations, object representations like
|
||||
'<__main__.Foo object at 0x23d8610>'
|
||||
|
||||
are turned into '<__main__.Foo>'. For even more descriptive names,
|
||||
especially in test logs, you can use the NamedParameters decorator. In
|
||||
especially in test logs, you can use the named_parameters decorator. In
|
||||
this case, only tuples are supported, and the first parameters has to
|
||||
be a string (or an object that returns an apt name when converted via
|
||||
str()):
|
||||
|
||||
class NamedExample(parameterized.ParameterizedTestCase):
|
||||
@parameterized.NamedParameters(
|
||||
class NamedExample(parameterized.TestCase):
|
||||
@parameterized.named_parameters(
|
||||
('Normal', 'aa', 'aaa', True),
|
||||
('EmptyPrefix', '', 'abc', True),
|
||||
('BothEmpty', '', '', True))
|
||||
@ -103,13 +103,13 @@ from the command line:
|
||||
Parameterized Classes
|
||||
=====================
|
||||
If invocation arguments are shared across test methods in a single
|
||||
ParameterizedTestCase class, instead of decorating all test methods
|
||||
TestCase class, instead of decorating all test methods
|
||||
individually, the class itself can be decorated:
|
||||
|
||||
@parameterized.Parameters(
|
||||
@parameterized.parameters(
|
||||
(1, 2, 3)
|
||||
(4, 5, 9))
|
||||
class ArithmeticTest(parameterized.ParameterizedTestCase):
|
||||
class ArithmeticTest(parameterized.TestCase):
|
||||
def testAdd(self, arg1, arg2, result):
|
||||
self.assertEqual(arg1 + arg2, result)
|
||||
|
||||
@ -122,8 +122,8 @@ If parameters should be shared across several test cases, or are dynamically
|
||||
created from other sources, a single non-tuple iterable can be passed into
|
||||
the decorator. This iterable will be used to obtain the test cases:
|
||||
|
||||
class AdditionExample(parameterized.ParameterizedTestCase):
|
||||
@parameterized.Parameters(
|
||||
class AdditionExample(parameterized.TestCase):
|
||||
@parameterized.parameters(
|
||||
c.op1, c.op2, c.result for c in testcases
|
||||
)
|
||||
def testAddition(self, op1, op2, result):
|
||||
@ -135,8 +135,8 @@ Single-Argument Test Methods
|
||||
If a test method takes only one argument, the single argument does not need to
|
||||
be wrapped into a tuple:
|
||||
|
||||
class NegativeNumberExample(parameterized.ParameterizedTestCase):
|
||||
@parameterized.Parameters(
|
||||
class NegativeNumberExample(parameterized.TestCase):
|
||||
@parameterized.parameters(
|
||||
-1, -3, -4, -5
|
||||
)
|
||||
def testIsNegative(self, arg):
|
||||
@ -212,7 +212,7 @@ class _ParameterizedTestIter(object):
|
||||
def __call__(self, *args, **kwargs):
|
||||
raise RuntimeError('You appear to be running a parameterized test case '
|
||||
'without having inherited from parameterized.'
|
||||
'ParameterizedTestCase. This is bad because none of '
|
||||
'TestCase. This is bad because none of '
|
||||
'your test cases are actually being run.')
|
||||
|
||||
def __iter__(self):
|
||||
@ -306,7 +306,7 @@ def _ParameterDecorator(naming_type, testcases):
|
||||
return _Apply
|
||||
|
||||
|
||||
def Parameters(*testcases):
|
||||
def parameters(*testcases): # pylint: disable=invalid-name
|
||||
"""A decorator for creating parameterized tests.
|
||||
|
||||
See the module docstring for a usage example.
|
||||
@ -321,7 +321,7 @@ def Parameters(*testcases):
|
||||
return _ParameterDecorator(_ARGUMENT_REPR, testcases)
|
||||
|
||||
|
||||
def NamedParameters(*testcases):
|
||||
def named_parameters(*testcases): # pylint: disable=invalid-name
|
||||
"""A decorator for creating parameterized tests.
|
||||
|
||||
See the module docstring for a usage example. The first element of
|
||||
@ -348,7 +348,7 @@ class TestGeneratorMetaclass(type):
|
||||
up as tests by the unittest framework.
|
||||
|
||||
In general, it is supposed to be used in conjunction with the
|
||||
Parameters decorator.
|
||||
parameters decorator.
|
||||
"""
|
||||
|
||||
def __new__(mcs, class_name, bases, dct):
|
||||
@ -385,8 +385,8 @@ def _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator):
|
||||
id_suffix[new_name] = getattr(func, '__x_extra_id__', '')
|
||||
|
||||
|
||||
class ParameterizedTestCase(unittest.TestCase):
|
||||
"""Base class for test cases using the Parameters decorator."""
|
||||
class TestCase(unittest.TestCase):
|
||||
"""Base class for test cases using the parameters decorator."""
|
||||
__metaclass__ = TestGeneratorMetaclass
|
||||
|
||||
def _OriginalName(self):
|
||||
@ -409,10 +409,10 @@ class ParameterizedTestCase(unittest.TestCase):
|
||||
self._id_suffix.get(self._testMethodName, ''))
|
||||
|
||||
|
||||
def CoopParameterizedTestCase(other_base_class):
|
||||
def CoopTestCase(other_base_class):
|
||||
"""Returns a new base class with a cooperative metaclass base.
|
||||
|
||||
This enables the ParameterizedTestCase to be used in combination
|
||||
This enables the TestCase to be used in combination
|
||||
with other base classes that have custom metaclasses, such as
|
||||
mox.MoxTestBase.
|
||||
|
||||
@ -425,7 +425,7 @@ def CoopParameterizedTestCase(other_base_class):
|
||||
|
||||
from google3.testing.pybase import parameterized
|
||||
|
||||
class ExampleTest(parameterized.CoopParameterizedTestCase(mox.MoxTestBase)):
|
||||
class ExampleTest(parameterized.CoopTestCase(mox.MoxTestBase)):
|
||||
...
|
||||
|
||||
Args:
|
||||
@ -439,5 +439,5 @@ def CoopParameterizedTestCase(other_base_class):
|
||||
(other_base_class.__metaclass__,
|
||||
TestGeneratorMetaclass), {})
|
||||
return metaclass(
|
||||
'CoopParameterizedTestCase',
|
||||
(other_base_class, ParameterizedTestCase), {})
|
||||
'CoopTestCase',
|
||||
(other_base_class, TestCase), {})
|
||||
|
@ -66,10 +66,13 @@ if _api_version < 0: # Still unspecified?
|
||||
from google.protobuf.internal import use_pure_python
|
||||
del use_pure_python # Avoids a pylint error and namespace pollution.
|
||||
except ImportError:
|
||||
if _proto_extension_modules_exist_in_build:
|
||||
if sys.version_info[0] >= 3: # Python 3 defaults to C++ impl v2.
|
||||
_api_version = 2
|
||||
# TODO(b/17427486): Make Python 2 default to C++ impl v2.
|
||||
# TODO(b/74017912): It's unsafe to enable :use_fast_cpp_protos by default;
|
||||
# it can cause data loss if you have any Python-only extensions to any
|
||||
# message passed back and forth with C++ code.
|
||||
#
|
||||
# TODO(b/17427486): Once that bug is fixed, we want to make both Python 2
|
||||
# and Python 3 default to `_api_version = 2` (C++ implementation V2).
|
||||
pass
|
||||
|
||||
_default_implementation_type = (
|
||||
'python' if _api_version <= 0 else 'cpp')
|
||||
|
@ -372,7 +372,7 @@ def MapSizer(field_descriptor, is_message_map):
|
||||
def _VarintEncoder():
|
||||
"""Return an encoder for a basic varint value (does not include tag)."""
|
||||
|
||||
def EncodeVarint(write, value, unused_deterministic):
|
||||
def EncodeVarint(write, value, unused_deterministic=None):
|
||||
bits = value & 0x7f
|
||||
value >>= 7
|
||||
while value:
|
||||
@ -388,7 +388,7 @@ def _SignedVarintEncoder():
|
||||
"""Return an encoder for a basic signed varint value (does not include
|
||||
tag)."""
|
||||
|
||||
def EncodeSignedVarint(write, value, unused_deterministic):
|
||||
def EncodeSignedVarint(write, value, unused_deterministic=None):
|
||||
if value < 0:
|
||||
value += (1 << 64)
|
||||
bits = value & 0x7f
|
||||
@ -524,14 +524,14 @@ def _StructPackEncoder(wire_type, format):
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeRepeatedField(write, value, unused_deterministic):
|
||||
def EncodeRepeatedField(write, value, unused_deterministic=None):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
write(local_struct_pack(format, element))
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeField(write, value, unused_deterministic):
|
||||
def EncodeField(write, value, unused_deterministic=None):
|
||||
write(tag_bytes)
|
||||
return write(local_struct_pack(format, value))
|
||||
return EncodeField
|
||||
@ -595,7 +595,7 @@ def _FloatingPointEncoder(wire_type, format):
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeRepeatedField(write, value, unused_deterministic):
|
||||
def EncodeRepeatedField(write, value, unused_deterministic=None):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
try:
|
||||
@ -605,7 +605,7 @@ def _FloatingPointEncoder(wire_type, format):
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeField(write, value, unused_deterministic):
|
||||
def EncodeField(write, value, unused_deterministic=None):
|
||||
write(tag_bytes)
|
||||
try:
|
||||
write(local_struct_pack(format, value))
|
||||
@ -662,7 +662,7 @@ def BoolEncoder(field_number, is_repeated, is_packed):
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
|
||||
def EncodeRepeatedField(write, value, unused_deterministic):
|
||||
def EncodeRepeatedField(write, value, unused_deterministic=None):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
if element:
|
||||
@ -672,7 +672,7 @@ def BoolEncoder(field_number, is_repeated, is_packed):
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
|
||||
def EncodeField(write, value, unused_deterministic):
|
||||
def EncodeField(write, value, unused_deterministic=None):
|
||||
write(tag_bytes)
|
||||
if value:
|
||||
return write(true_byte)
|
||||
|
@ -983,6 +983,18 @@ class JsonFormatTest(JsonFormatBase):
|
||||
self.assertEqual('{\n"int32Value": 12345\n}',
|
||||
json_format.MessageToJson(message, indent=0))
|
||||
|
||||
def testFormatEnumsAsInts(self):
|
||||
message = json_format_proto3_pb2.TestMessage()
|
||||
message.enum_value = json_format_proto3_pb2.BAR
|
||||
message.repeated_enum_value.append(json_format_proto3_pb2.FOO)
|
||||
message.repeated_enum_value.append(json_format_proto3_pb2.BAR)
|
||||
self.assertEqual(json.loads('{\n'
|
||||
' "enumValue": 1,\n'
|
||||
' "repeatedEnumValue": [0, 1]\n'
|
||||
'}\n'),
|
||||
json.loads(json_format.MessageToJson(
|
||||
message, use_integers_for_enums=True)))
|
||||
|
||||
def testParseDict(self):
|
||||
expected = 12345
|
||||
js_dict = {'int32Value': expected}
|
||||
|
@ -99,7 +99,7 @@ def IsNegInf(val):
|
||||
BaseTestCase = testing_refleaks.BaseTestCase
|
||||
|
||||
|
||||
@_parameterized.NamedParameters(
|
||||
@_parameterized.named_parameters(
|
||||
('_proto2', unittest_pb2),
|
||||
('_proto3', unittest_proto3_arena_pb2))
|
||||
class MessageTest(BaseTestCase):
|
||||
@ -1694,6 +1694,33 @@ class Proto3Test(BaseTestCase):
|
||||
with self.assertRaises(TypeError):
|
||||
del msg2.map_int32_foreign_message['']
|
||||
|
||||
def testMapMergeFrom(self):
|
||||
msg = map_unittest_pb2.TestMap()
|
||||
msg.map_int32_int32[12] = 34
|
||||
msg.map_int32_int32[56] = 78
|
||||
msg.map_int64_int64[22] = 33
|
||||
msg.map_int32_foreign_message[111].c = 5
|
||||
msg.map_int32_foreign_message[222].c = 10
|
||||
|
||||
msg2 = map_unittest_pb2.TestMap()
|
||||
msg2.map_int32_int32[12] = 55
|
||||
msg2.map_int64_int64[88] = 99
|
||||
msg2.map_int32_foreign_message[222].c = 15
|
||||
msg2.map_int32_foreign_message[222].d = 20
|
||||
|
||||
msg2.map_int32_int32.MergeFrom(msg.map_int32_int32)
|
||||
self.assertEqual(34, msg2.map_int32_int32[12])
|
||||
self.assertEqual(78, msg2.map_int32_int32[56])
|
||||
|
||||
msg2.map_int64_int64.MergeFrom(msg.map_int64_int64)
|
||||
self.assertEqual(33, msg2.map_int64_int64[22])
|
||||
self.assertEqual(99, msg2.map_int64_int64[88])
|
||||
|
||||
msg2.map_int32_foreign_message.MergeFrom(msg.map_int32_foreign_message)
|
||||
self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
|
||||
self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
|
||||
self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d'))
|
||||
|
||||
def testMergeFromBadType(self):
|
||||
msg = map_unittest_pb2.TestMap()
|
||||
with self.assertRaisesRegexp(
|
||||
|
12
python/google/protobuf/internal/no_package.proto
Normal file
12
python/google/protobuf/internal/no_package.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto2";
|
||||
|
||||
option py_api_version = 2;
|
||||
|
||||
enum NoPackageEnum {
|
||||
NO_PACKAGE_VALUE_0 = 0;
|
||||
NO_PACKAGE_VALUE_1 = 1;
|
||||
}
|
||||
|
||||
message NoPackageMessage {
|
||||
optional NoPackageEnum no_package_enum = 1;
|
||||
}
|
@ -48,6 +48,7 @@ except ImportError:
|
||||
|
||||
from google.protobuf.internal import _parameterized
|
||||
|
||||
from google.protobuf import any_pb2
|
||||
from google.protobuf import any_test_pb2
|
||||
from google.protobuf import map_unittest_pb2
|
||||
from google.protobuf import unittest_mset_pb2
|
||||
@ -99,7 +100,7 @@ class TextFormatBase(unittest.TestCase):
|
||||
return text
|
||||
|
||||
|
||||
@_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2))
|
||||
@_parameterized.parameters((unittest_pb2), (unittest_proto3_arena_pb2))
|
||||
class TextFormatTest(TextFormatBase):
|
||||
|
||||
def testPrintExotic(self, message_module):
|
||||
@ -369,6 +370,7 @@ class TextFormatTest(TextFormatBase):
|
||||
def testParseRepeatedScalarShortFormat(self, message_module):
|
||||
message = message_module.TestAllTypes()
|
||||
text = ('repeated_int64: [100, 200];\n'
|
||||
'repeated_int64: []\n'
|
||||
'repeated_int64: 300,\n'
|
||||
'repeated_string: ["one", "two"];\n')
|
||||
text_format.Parse(text, message)
|
||||
@ -524,20 +526,68 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
|
||||
|
||||
def testPrintInIndexOrder(self):
|
||||
message = unittest_pb2.TestFieldOrderings()
|
||||
message.my_string = '115'
|
||||
# Fields are listed in index order instead of field number.
|
||||
message.my_string = 'str'
|
||||
message.my_int = 101
|
||||
message.my_float = 111
|
||||
message.optional_nested_message.oo = 0
|
||||
message.optional_nested_message.bb = 1
|
||||
message.Extensions[unittest_pb2.my_extension_string] = 'ext_str0'
|
||||
# Extensions are listed based on the order of extension number.
|
||||
# Extension number 12.
|
||||
message.Extensions[unittest_pb2.TestExtensionOrderings2.
|
||||
test_ext_orderings2].my_string = 'ext_str2'
|
||||
# Extension number 13.
|
||||
message.Extensions[unittest_pb2.TestExtensionOrderings1.
|
||||
test_ext_orderings1].my_string = 'ext_str1'
|
||||
# Extension number 14.
|
||||
message.Extensions[
|
||||
unittest_pb2.TestExtensionOrderings2.TestExtensionOrderings3.
|
||||
test_ext_orderings3].my_string = 'ext_str3'
|
||||
|
||||
# Print in index order.
|
||||
self.CompareToGoldenText(
|
||||
self.RemoveRedundantZeros(text_format.MessageToString(
|
||||
message, use_index_order=True)),
|
||||
'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n'
|
||||
'optional_nested_message {\n oo: 0\n bb: 1\n}\n')
|
||||
self.RemoveRedundantZeros(
|
||||
text_format.MessageToString(message, use_index_order=True)),
|
||||
'my_string: "str"\n'
|
||||
'my_int: 101\n'
|
||||
'my_float: 111\n'
|
||||
'optional_nested_message {\n'
|
||||
' oo: 0\n'
|
||||
' bb: 1\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] {\n'
|
||||
' my_string: "ext_str2"\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.TestExtensionOrderings1.test_ext_orderings1] {\n'
|
||||
' my_string: "ext_str1"\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3'
|
||||
'.test_ext_orderings3] {\n'
|
||||
' my_string: "ext_str3"\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.my_extension_string]: "ext_str0"\n')
|
||||
# By default, print in field number order.
|
||||
self.CompareToGoldenText(
|
||||
self.RemoveRedundantZeros(text_format.MessageToString(message)),
|
||||
'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n'
|
||||
'optional_nested_message {\n bb: 1\n oo: 0\n}\n')
|
||||
'my_int: 101\n'
|
||||
'my_string: "str"\n'
|
||||
'[protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] {\n'
|
||||
' my_string: "ext_str2"\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.TestExtensionOrderings1.test_ext_orderings1] {\n'
|
||||
' my_string: "ext_str1"\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3'
|
||||
'.test_ext_orderings3] {\n'
|
||||
' my_string: "ext_str3"\n'
|
||||
'}\n'
|
||||
'[protobuf_unittest.my_extension_string]: "ext_str0"\n'
|
||||
'my_float: 111\n'
|
||||
'optional_nested_message {\n'
|
||||
' bb: 1\n'
|
||||
' oo: 0\n'
|
||||
'}\n')
|
||||
|
||||
def testMergeLinesGolden(self):
|
||||
opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
|
||||
@ -970,15 +1020,26 @@ class Proto2Tests(TextFormatBase):
|
||||
'"protobuf_unittest.optional_int32_extension" extensions.'),
|
||||
text_format.Parse, text, message)
|
||||
|
||||
def testParseDuplicateNestedMessageScalars(self):
|
||||
def testParseDuplicateMessages(self):
|
||||
message = unittest_pb2.TestAllTypes()
|
||||
text = ('optional_nested_message { bb: 1 } '
|
||||
'optional_nested_message { bb: 2 }')
|
||||
six.assertRaisesRegex(self, text_format.ParseError, (
|
||||
'1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
|
||||
'should not have multiple "bb" fields.'), text_format.Parse, text,
|
||||
'1:59 : Message type "protobuf_unittest.TestAllTypes" '
|
||||
'should not have multiple "optional_nested_message" fields.'),
|
||||
text_format.Parse, text,
|
||||
message)
|
||||
|
||||
def testParseDuplicateExtensionMessages(self):
|
||||
message = unittest_pb2.TestAllExtensions()
|
||||
text = ('[protobuf_unittest.optional_nested_message_extension]: {} '
|
||||
'[protobuf_unittest.optional_nested_message_extension]: {}')
|
||||
six.assertRaisesRegex(self, text_format.ParseError, (
|
||||
'1:114 : Message type "protobuf_unittest.TestAllExtensions" '
|
||||
'should not have multiple '
|
||||
'"protobuf_unittest.optional_nested_message_extension" extensions.'),
|
||||
text_format.Parse, text, message)
|
||||
|
||||
def testParseDuplicateScalars(self):
|
||||
message = unittest_pb2.TestAllTypes()
|
||||
text = ('optional_int32: 42 ' 'optional_int32: 67')
|
||||
@ -1065,6 +1126,14 @@ class Proto3Tests(unittest.TestCase):
|
||||
' }\n'
|
||||
'}\n')
|
||||
|
||||
def testTopAnyMessage(self):
|
||||
packed_msg = unittest_pb2.OneString()
|
||||
msg = any_pb2.Any()
|
||||
msg.Pack(packed_msg)
|
||||
text = text_format.MessageToString(msg)
|
||||
other_msg = text_format.Parse(text, any_pb2.Any())
|
||||
self.assertEqual(msg, other_msg)
|
||||
|
||||
def testPrintMessageExpandAnyRepeated(self):
|
||||
packed_message = unittest_pb2.OneString()
|
||||
message = any_test_pb2.TestAny()
|
||||
@ -1489,7 +1558,7 @@ class TokenizerTest(unittest.TestCase):
|
||||
|
||||
|
||||
# Tests for pretty printer functionality.
|
||||
@_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2))
|
||||
@_parameterized.parameters((unittest_pb2), (unittest_proto3_arena_pb2))
|
||||
class PrettyPrinterTest(TextFormatBase):
|
||||
|
||||
def testPrettyPrintNoMatch(self, message_module):
|
||||
|
@ -375,6 +375,9 @@ def _CheckDurationValid(seconds, nanos):
|
||||
raise Error(
|
||||
'Duration is not valid: Nanos {0} must be in range '
|
||||
'[-999999999, 999999999].'.format(nanos))
|
||||
if (nanos < 0 and seconds > 0) or (nanos > 0 and seconds < 0):
|
||||
raise Error(
|
||||
'Duration is not valid: Sign mismatch.')
|
||||
|
||||
|
||||
def _RoundTowardZero(value, divider):
|
||||
@ -649,9 +652,10 @@ def _MergeMessage(
|
||||
raise ValueError('Error: Field {0} in message {1} is not a singular '
|
||||
'message field and cannot have sub-fields.'.format(
|
||||
name, source_descriptor.full_name))
|
||||
_MergeMessage(
|
||||
child, getattr(source, name), getattr(destination, name),
|
||||
replace_message, replace_repeated)
|
||||
if source.HasField(name):
|
||||
_MergeMessage(
|
||||
child, getattr(source, name), getattr(destination, name),
|
||||
replace_message, replace_repeated)
|
||||
continue
|
||||
if field.label == FieldDescriptor.LABEL_REPEATED:
|
||||
if replace_repeated:
|
||||
|
@ -345,6 +345,12 @@ class TimeUtilTest(TimeUtilTestBase):
|
||||
r'Duration is not valid\: Nanos 1000000000 must be in range'
|
||||
r' \[-999999999\, 999999999\].',
|
||||
message.ToJsonString)
|
||||
message.seconds = -1
|
||||
message.nanos = 1
|
||||
self.assertRaisesRegexp(
|
||||
well_known_types.Error,
|
||||
r'Duration is not valid\: Sign mismatch.',
|
||||
message.ToJsonString)
|
||||
|
||||
|
||||
class FieldMaskTest(unittest.TestCase):
|
||||
@ -599,6 +605,16 @@ class FieldMaskTest(unittest.TestCase):
|
||||
self.assertEqual(1, len(nested_dst.payload.repeated_int32))
|
||||
self.assertEqual(1234, nested_dst.payload.repeated_int32[0])
|
||||
|
||||
# Test Merge oneof field.
|
||||
new_msg = unittest_pb2.TestOneof2()
|
||||
dst = unittest_pb2.TestOneof2()
|
||||
dst.foo_message.qux_int = 1
|
||||
mask = field_mask_pb2.FieldMask()
|
||||
mask.FromJsonString('fooMessage,fooLazyMessage.quxInt')
|
||||
mask.MergeMessage(new_msg, dst)
|
||||
self.assertTrue(dst.HasField('foo_message'))
|
||||
self.assertFalse(dst.HasField('foo_lazy_message'))
|
||||
|
||||
def testMergeErrors(self):
|
||||
src = unittest_pb2.TestAllTypes()
|
||||
dst = unittest_pb2.TestAllTypes()
|
||||
|
@ -42,21 +42,28 @@ Simple usage example:
|
||||
|
||||
__author__ = 'jieluo@google.com (Jie Luo)'
|
||||
|
||||
# pylint: disable=g-statement-before-imports,g-import-not-at-top
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from ordereddict import OrderedDict #PY26
|
||||
from ordereddict import OrderedDict # PY26
|
||||
# pylint: enable=g-statement-before-imports,g-import-not-at-top
|
||||
|
||||
import base64
|
||||
import json
|
||||
import math
|
||||
import re
|
||||
import six
|
||||
import sys
|
||||
|
||||
from operator import methodcaller
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
import six
|
||||
|
||||
from google.protobuf import descriptor
|
||||
from google.protobuf import symbol_database
|
||||
|
||||
|
||||
_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S'
|
||||
_INT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT32,
|
||||
descriptor.FieldDescriptor.CPPTYPE_UINT32,
|
||||
@ -93,7 +100,8 @@ def MessageToJson(message,
|
||||
including_default_value_fields=False,
|
||||
preserving_proto_field_name=False,
|
||||
indent=2,
|
||||
sort_keys=False):
|
||||
sort_keys=False,
|
||||
use_integers_for_enums=False):
|
||||
"""Converts protobuf message to JSON format.
|
||||
|
||||
Args:
|
||||
@ -108,18 +116,21 @@ def MessageToJson(message,
|
||||
indent: The JSON object will be pretty-printed with this indent level.
|
||||
An indent level of 0 or negative will only insert newlines.
|
||||
sort_keys: If True, then the output will be sorted by field names.
|
||||
use_integers_for_enums: If true, print integers instead of enum names.
|
||||
|
||||
Returns:
|
||||
A string containing the JSON formatted protocol buffer message.
|
||||
"""
|
||||
printer = _Printer(including_default_value_fields,
|
||||
preserving_proto_field_name)
|
||||
preserving_proto_field_name,
|
||||
use_integers_for_enums)
|
||||
return printer.ToJsonString(message, indent, sort_keys)
|
||||
|
||||
|
||||
def MessageToDict(message,
|
||||
including_default_value_fields=False,
|
||||
preserving_proto_field_name=False):
|
||||
preserving_proto_field_name=False,
|
||||
use_integers_for_enums=False):
|
||||
"""Converts protobuf message to a dictionary.
|
||||
|
||||
When the dictionary is encoded to JSON, it conforms to proto3 JSON spec.
|
||||
@ -133,12 +144,14 @@ def MessageToDict(message,
|
||||
preserving_proto_field_name: If True, use the original proto field
|
||||
names as defined in the .proto file. If False, convert the field
|
||||
names to lowerCamelCase.
|
||||
use_integers_for_enums: If true, print integers instead of enum names.
|
||||
|
||||
Returns:
|
||||
A dict representation of the protocol buffer message.
|
||||
"""
|
||||
printer = _Printer(including_default_value_fields,
|
||||
preserving_proto_field_name)
|
||||
preserving_proto_field_name,
|
||||
use_integers_for_enums)
|
||||
# pylint: disable=protected-access
|
||||
return printer._MessageToJsonObject(message)
|
||||
|
||||
@ -154,9 +167,11 @@ class _Printer(object):
|
||||
|
||||
def __init__(self,
|
||||
including_default_value_fields=False,
|
||||
preserving_proto_field_name=False):
|
||||
preserving_proto_field_name=False,
|
||||
use_integers_for_enums=False):
|
||||
self.including_default_value_fields = including_default_value_fields
|
||||
self.preserving_proto_field_name = preserving_proto_field_name
|
||||
self.use_integers_for_enums = use_integers_for_enums
|
||||
|
||||
def ToJsonString(self, message, indent, sort_keys):
|
||||
js = self._MessageToJsonObject(message)
|
||||
@ -247,6 +262,8 @@ class _Printer(object):
|
||||
if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
|
||||
return self._MessageToJsonObject(value)
|
||||
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
|
||||
if self.use_integers_for_enums:
|
||||
return value
|
||||
enum_value = field.enum_type.values_by_number.get(value, None)
|
||||
if enum_value is not None:
|
||||
return enum_value.name
|
||||
|
@ -188,38 +188,35 @@ const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) {
|
||||
// Always returns a new reference.
|
||||
template<class DescriptorClass>
|
||||
static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
|
||||
// Options (and their extensions) are completely resolved in the proto file
|
||||
// containing the descriptor.
|
||||
PyDescriptorPool* pool = GetDescriptorPool_FromPool(
|
||||
GetFileDescriptor(descriptor)->pool());
|
||||
|
||||
hash_map<const void*, PyObject*>* descriptor_options =
|
||||
pool->descriptor_options;
|
||||
// Options are cached in the pool that owns the descriptor.
|
||||
// First search in the cache.
|
||||
PyDescriptorPool* caching_pool = GetDescriptorPool_FromPool(
|
||||
GetFileDescriptor(descriptor)->pool());
|
||||
hash_map<const void*, PyObject*>* descriptor_options =
|
||||
caching_pool->descriptor_options;
|
||||
if (descriptor_options->find(descriptor) != descriptor_options->end()) {
|
||||
PyObject *value = (*descriptor_options)[descriptor];
|
||||
Py_INCREF(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
// Similar to the C++ implementation, we return an Options object from the
|
||||
// default (generated) factory, so that client code know that they can use
|
||||
// extensions from generated files:
|
||||
// d.GetOptions().Extensions[some_pb2.extension]
|
||||
//
|
||||
// The consequence is that extensions not defined in the default pool won't
|
||||
// be available. If needed, we could add an optional 'message_factory'
|
||||
// parameter to the GetOptions() function.
|
||||
PyMessageFactory* message_factory =
|
||||
GetDefaultDescriptorPool()->py_message_factory;
|
||||
|
||||
// Build the Options object: get its Python class, and make a copy of the C++
|
||||
// read-only instance.
|
||||
const Message& options(descriptor->options());
|
||||
const Descriptor *message_type = options.GetDescriptor();
|
||||
PyMessageFactory* message_factory = pool->py_message_factory;
|
||||
CMessageClass* message_class = message_factory::GetMessageClass(
|
||||
CMessageClass* message_class = message_factory::GetOrCreateMessageClass(
|
||||
message_factory, message_type);
|
||||
if (message_class == NULL) {
|
||||
// The Options message was not found in the current DescriptorPool.
|
||||
// This means that the pool cannot contain any extensions to the Options
|
||||
// message either, so falling back to the basic pool we can only increase
|
||||
// the chances of successfully parsing the options.
|
||||
PyErr_Clear();
|
||||
pool = GetDefaultDescriptorPool();
|
||||
message_factory = pool->py_message_factory;
|
||||
message_class = message_factory::GetMessageClass(
|
||||
message_factory, message_type);
|
||||
}
|
||||
if (message_class == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
|
||||
message_type->full_name().c_str());
|
||||
@ -248,7 +245,8 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
|
||||
options.SerializeToString(&serialized);
|
||||
io::CodedInputStream input(
|
||||
reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
|
||||
input.SetExtensionRegistry(pool->pool, message_factory->message_factory);
|
||||
input.SetExtensionRegistry(message_factory->pool->pool,
|
||||
message_factory->message_factory);
|
||||
bool success = cmsg->message->MergePartialFromCodedStream(&input);
|
||||
if (!success) {
|
||||
PyErr_Format(PyExc_ValueError, "Error parsing Options message");
|
||||
@ -564,6 +562,11 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
return CheckCalledFromGeneratedFile("_options");
|
||||
}
|
||||
|
||||
static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
void *closure) {
|
||||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
|
||||
return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
|
||||
}
|
||||
@ -623,6 +626,8 @@ static PyGetSetDef Getters[] = {
|
||||
{ "is_extendable", (getter)IsExtendable, (setter)NULL},
|
||||
{ "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
|
||||
{ "_options", (getter)NULL, (setter)SetOptions, "Options"},
|
||||
{ "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{ "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
|
||||
{NULL}
|
||||
};
|
||||
@ -785,7 +790,7 @@ static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::CPPTYPE_STRING: {
|
||||
string value = _GetDescriptor(self)->default_value_string();
|
||||
const string& value = _GetDescriptor(self)->default_value_string();
|
||||
result = ToStringObject(_GetDescriptor(self), value);
|
||||
break;
|
||||
}
|
||||
@ -897,6 +902,10 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
return CheckCalledFromGeneratedFile("_options");
|
||||
}
|
||||
|
||||
static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
void *closure) {
|
||||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
{ "full_name", (getter)GetFullName, NULL, "Full name"},
|
||||
@ -926,6 +935,8 @@ static PyGetSetDef Getters[] = {
|
||||
"Containing oneof"},
|
||||
{ "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
|
||||
{ "_options", (getter)NULL, (setter)SetOptions, "Options"},
|
||||
{ "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@ -1055,6 +1066,11 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
return CheckCalledFromGeneratedFile("_options");
|
||||
}
|
||||
|
||||
static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
void *closure) {
|
||||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
|
||||
return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
|
||||
}
|
||||
@ -1079,6 +1095,8 @@ static PyGetSetDef Getters[] = {
|
||||
"Containing type"},
|
||||
{ "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
|
||||
{ "_options", (getter)NULL, (setter)SetOptions, "Options"},
|
||||
{ "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@ -1179,6 +1197,10 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
return CheckCalledFromGeneratedFile("_options");
|
||||
}
|
||||
|
||||
static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
void *closure) {
|
||||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
{ "name", (getter)GetName, NULL, "name"},
|
||||
@ -1188,6 +1210,8 @@ static PyGetSetDef Getters[] = {
|
||||
|
||||
{ "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
|
||||
{ "_options", (getter)NULL, (setter)SetOptions, "Options"},
|
||||
{ "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@ -1330,6 +1354,11 @@ static int SetOptions(PyFileDescriptor *self, PyObject *value,
|
||||
return CheckCalledFromGeneratedFile("_options");
|
||||
}
|
||||
|
||||
static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value,
|
||||
void *closure) {
|
||||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
|
||||
return PyString_InternFromString(
|
||||
FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
|
||||
@ -1355,6 +1384,8 @@ static PyGetSetDef Getters[] = {
|
||||
|
||||
{ "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
|
||||
{ "_options", (getter)NULL, (setter)SetOptions, "Options"},
|
||||
{ "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{ "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
|
||||
{NULL}
|
||||
};
|
||||
@ -1500,6 +1531,11 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
return CheckCalledFromGeneratedFile("_options");
|
||||
}
|
||||
|
||||
static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
|
||||
void *closure) {
|
||||
return CheckCalledFromGeneratedFile("_serialized_options");
|
||||
}
|
||||
|
||||
static PyGetSetDef Getters[] = {
|
||||
{ "name", (getter)GetName, NULL, "Name"},
|
||||
{ "full_name", (getter)GetFullName, NULL, "Full name"},
|
||||
@ -1508,6 +1544,8 @@ static PyGetSetDef Getters[] = {
|
||||
{ "containing_type", (getter)GetContainingType, NULL, "Containing type"},
|
||||
{ "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
|
||||
{ "_options", (getter)NULL, (setter)SetOptions, "Options"},
|
||||
{ "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
|
||||
"Serialized Options"},
|
||||
{ "fields", (getter)GetFields, NULL, "Fields"},
|
||||
{NULL}
|
||||
};
|
||||
|
@ -149,7 +149,8 @@ static PyObject* New(PyTypeObject* type,
|
||||
PyDescriptorPool_NewWithDatabase(database));
|
||||
}
|
||||
|
||||
static void Dealloc(PyDescriptorPool* self) {
|
||||
static void Dealloc(PyObject* pself) {
|
||||
PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
|
||||
descriptor_pool_map.erase(self->pool);
|
||||
Py_CLEAR(self->py_message_factory);
|
||||
for (hash_map<const void*, PyObject*>::iterator it =
|
||||
@ -163,7 +164,7 @@ static void Dealloc(PyDescriptorPool* self) {
|
||||
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
||||
}
|
||||
|
||||
PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
static PyObject* FindMessageByName(PyObject* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
||||
@ -171,7 +172,8 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
}
|
||||
|
||||
const Descriptor* message_descriptor =
|
||||
self->pool->FindMessageTypeByName(string(name, name_size));
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName(
|
||||
string(name, name_size));
|
||||
|
||||
if (message_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find message %.200s", name);
|
||||
@ -184,7 +186,7 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
|
||||
|
||||
|
||||
PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
static PyObject* FindFileByName(PyObject* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
||||
@ -192,7 +194,8 @@ PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
}
|
||||
|
||||
const FileDescriptor* file_descriptor =
|
||||
self->pool->FindFileByName(string(name, name_size));
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName(
|
||||
string(name, name_size));
|
||||
if (file_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s", name);
|
||||
return NULL;
|
||||
@ -218,6 +221,10 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyFieldDescriptor_FromDescriptor(field_descriptor);
|
||||
}
|
||||
|
||||
static PyObject* FindFieldByNameMethod(PyObject* self, PyObject* arg) {
|
||||
return FindFieldByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
|
||||
}
|
||||
|
||||
PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
@ -235,6 +242,10 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyFieldDescriptor_FromDescriptor(field_descriptor);
|
||||
}
|
||||
|
||||
static PyObject* FindExtensionByNameMethod(PyObject* self, PyObject* arg) {
|
||||
return FindExtensionByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
|
||||
}
|
||||
|
||||
PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
@ -252,6 +263,10 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyEnumDescriptor_FromDescriptor(enum_descriptor);
|
||||
}
|
||||
|
||||
static PyObject* FindEnumTypeByNameMethod(PyObject* self, PyObject* arg) {
|
||||
return FindEnumTypeByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
|
||||
}
|
||||
|
||||
PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
@ -269,7 +284,11 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyOneofDescriptor_FromDescriptor(oneof_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
static PyObject* FindOneofByNameMethod(PyObject* self, PyObject* arg) {
|
||||
return FindOneofByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
|
||||
}
|
||||
|
||||
static PyObject* FindServiceByName(PyObject* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
||||
@ -277,7 +296,8 @@ PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
}
|
||||
|
||||
const ServiceDescriptor* service_descriptor =
|
||||
self->pool->FindServiceByName(string(name, name_size));
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
|
||||
string(name, name_size));
|
||||
if (service_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name);
|
||||
return NULL;
|
||||
@ -286,7 +306,7 @@ PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyServiceDescriptor_FromDescriptor(service_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
static PyObject* FindMethodByName(PyObject* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
||||
@ -294,7 +314,8 @@ PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
}
|
||||
|
||||
const MethodDescriptor* method_descriptor =
|
||||
self->pool->FindMethodByName(string(name, name_size));
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMethodByName(
|
||||
string(name, name_size));
|
||||
if (method_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
|
||||
return NULL;
|
||||
@ -303,7 +324,7 @@ PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyMethodDescriptor_FromDescriptor(method_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
|
||||
static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
||||
@ -311,7 +332,8 @@ PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
|
||||
}
|
||||
|
||||
const FileDescriptor* file_descriptor =
|
||||
self->pool->FindFileContainingSymbol(string(name, name_size));
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileContainingSymbol(
|
||||
string(name, name_size));
|
||||
if (file_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find symbol %.200s", name);
|
||||
return NULL;
|
||||
@ -320,7 +342,7 @@ PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
|
||||
return PyFileDescriptor_FromDescriptor(file_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) {
|
||||
static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) {
|
||||
PyObject* message_descriptor;
|
||||
int number;
|
||||
if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) {
|
||||
@ -333,7 +355,8 @@ PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) {
|
||||
}
|
||||
|
||||
const FieldDescriptor* extension_descriptor =
|
||||
self->pool->FindExtensionByNumber(descriptor, number);
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByNumber(
|
||||
descriptor, number);
|
||||
if (extension_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find extension %d", number);
|
||||
return NULL;
|
||||
@ -342,14 +365,15 @@ PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) {
|
||||
return PyFieldDescriptor_FromDescriptor(extension_descriptor);
|
||||
}
|
||||
|
||||
PyObject* FindAllExtensions(PyDescriptorPool* self, PyObject* arg) {
|
||||
static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) {
|
||||
const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(arg);
|
||||
if (descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<const FieldDescriptor*> extensions;
|
||||
self->pool->FindAllExtensions(descriptor, &extensions);
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindAllExtensions(
|
||||
descriptor, &extensions);
|
||||
|
||||
ScopedPyObjectPtr result(PyList_New(extensions.size()));
|
||||
if (result == NULL) {
|
||||
@ -374,14 +398,15 @@ PyObject* FindAllExtensions(PyDescriptorPool* self, PyObject* arg) {
|
||||
// call a function that will just be a no-op?
|
||||
// TODO(amauryfa): Need to investigate further.
|
||||
|
||||
PyObject* AddFileDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) {
|
||||
const FileDescriptor* file_descriptor =
|
||||
PyFileDescriptor_AsDescriptor(descriptor);
|
||||
if (!file_descriptor) {
|
||||
return NULL;
|
||||
}
|
||||
if (file_descriptor !=
|
||||
self->pool->FindFileByName(file_descriptor->name())) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName(
|
||||
file_descriptor->name())) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The file descriptor %s does not belong to this pool",
|
||||
file_descriptor->name().c_str());
|
||||
@ -390,14 +415,15 @@ PyObject* AddFileDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* AddDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) {
|
||||
const Descriptor* message_descriptor =
|
||||
PyMessageDescriptor_AsDescriptor(descriptor);
|
||||
if (!message_descriptor) {
|
||||
return NULL;
|
||||
}
|
||||
if (message_descriptor !=
|
||||
self->pool->FindMessageTypeByName(message_descriptor->full_name())) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName(
|
||||
message_descriptor->full_name())) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The message descriptor %s does not belong to this pool",
|
||||
message_descriptor->full_name().c_str());
|
||||
@ -406,14 +432,15 @@ PyObject* AddDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) {
|
||||
const EnumDescriptor* enum_descriptor =
|
||||
PyEnumDescriptor_AsDescriptor(descriptor);
|
||||
if (!enum_descriptor) {
|
||||
return NULL;
|
||||
}
|
||||
if (enum_descriptor !=
|
||||
self->pool->FindEnumTypeByName(enum_descriptor->full_name())) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindEnumTypeByName(
|
||||
enum_descriptor->full_name())) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The enum descriptor %s does not belong to this pool",
|
||||
enum_descriptor->full_name().c_str());
|
||||
@ -422,14 +449,15 @@ PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
static PyObject* AddExtensionDescriptor(PyObject* 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())) {
|
||||
reinterpret_cast<PyDescriptorPool*>(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());
|
||||
@ -438,14 +466,15 @@ PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* AddServiceDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
||||
static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) {
|
||||
const ServiceDescriptor* service_descriptor =
|
||||
PyServiceDescriptor_AsDescriptor(descriptor);
|
||||
if (!service_descriptor) {
|
||||
return NULL;
|
||||
}
|
||||
if (service_descriptor !=
|
||||
self->pool->FindServiceByName(service_descriptor->full_name())) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
|
||||
service_descriptor->full_name())) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"The service descriptor %s does not belong to this pool",
|
||||
service_descriptor->full_name().c_str());
|
||||
@ -481,7 +510,8 @@ class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
|
||||
bool had_errors;
|
||||
};
|
||||
|
||||
PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) {
|
||||
static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) {
|
||||
PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
|
||||
char* message_type;
|
||||
Py_ssize_t message_len;
|
||||
|
||||
@ -529,7 +559,7 @@ PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) {
|
||||
descriptor, serialized_pb);
|
||||
}
|
||||
|
||||
PyObject* Add(PyDescriptorPool* self, PyObject* file_descriptor_proto) {
|
||||
static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) {
|
||||
ScopedPyObjectPtr serialized_pb(
|
||||
PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL));
|
||||
if (serialized_pb == NULL) {
|
||||
@ -539,46 +569,46 @@ PyObject* Add(PyDescriptorPool* self, PyObject* file_descriptor_proto) {
|
||||
}
|
||||
|
||||
static PyMethodDef Methods[] = {
|
||||
{ "Add", (PyCFunction)Add, METH_O,
|
||||
{ "Add", Add, METH_O,
|
||||
"Adds the FileDescriptorProto and its types to this pool." },
|
||||
{ "AddSerializedFile", (PyCFunction)AddSerializedFile, METH_O,
|
||||
{ "AddSerializedFile", AddSerializedFile, METH_O,
|
||||
"Adds a serialized FileDescriptorProto to this pool." },
|
||||
|
||||
// TODO(amauryfa): Understand why the Python implementation differs from
|
||||
// this one, ask users to use another API and deprecate these functions.
|
||||
{ "AddFileDescriptor", (PyCFunction)AddFileDescriptor, METH_O,
|
||||
{ "AddFileDescriptor", AddFileDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
{ "AddDescriptor", (PyCFunction)AddDescriptor, METH_O,
|
||||
{ "AddDescriptor", AddDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
{ "AddEnumDescriptor", (PyCFunction)AddEnumDescriptor, METH_O,
|
||||
{ "AddEnumDescriptor", AddEnumDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
{ "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O,
|
||||
{ "AddExtensionDescriptor", AddExtensionDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
{ "AddServiceDescriptor", (PyCFunction)AddServiceDescriptor, METH_O,
|
||||
{ "AddServiceDescriptor", AddServiceDescriptor, METH_O,
|
||||
"No-op. Add() must have been called before." },
|
||||
|
||||
{ "FindFileByName", (PyCFunction)FindFileByName, METH_O,
|
||||
{ "FindFileByName", FindFileByName, METH_O,
|
||||
"Searches for a file descriptor by its .proto name." },
|
||||
{ "FindMessageTypeByName", (PyCFunction)FindMessageByName, METH_O,
|
||||
{ "FindMessageTypeByName", FindMessageByName, METH_O,
|
||||
"Searches for a message descriptor by full name." },
|
||||
{ "FindFieldByName", (PyCFunction)FindFieldByName, METH_O,
|
||||
{ "FindFieldByName", FindFieldByNameMethod, METH_O,
|
||||
"Searches for a field descriptor by full name." },
|
||||
{ "FindExtensionByName", (PyCFunction)FindExtensionByName, METH_O,
|
||||
{ "FindExtensionByName", FindExtensionByNameMethod, METH_O,
|
||||
"Searches for extension descriptor by full name." },
|
||||
{ "FindEnumTypeByName", (PyCFunction)FindEnumTypeByName, METH_O,
|
||||
{ "FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O,
|
||||
"Searches for enum type descriptor by full name." },
|
||||
{ "FindOneofByName", (PyCFunction)FindOneofByName, METH_O,
|
||||
{ "FindOneofByName", FindOneofByNameMethod, METH_O,
|
||||
"Searches for oneof descriptor by full name." },
|
||||
{ "FindServiceByName", (PyCFunction)FindServiceByName, METH_O,
|
||||
{ "FindServiceByName", FindServiceByName, METH_O,
|
||||
"Searches for service descriptor by full name." },
|
||||
{ "FindMethodByName", (PyCFunction)FindMethodByName, METH_O,
|
||||
{ "FindMethodByName", FindMethodByName, METH_O,
|
||||
"Searches for method descriptor by full name." },
|
||||
|
||||
{ "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O,
|
||||
{ "FindFileContainingSymbol", FindFileContainingSymbol, METH_O,
|
||||
"Gets the FileDescriptor containing the specified symbol." },
|
||||
{ "FindExtensionByNumber", (PyCFunction)FindExtensionByNumber, METH_VARARGS,
|
||||
{ "FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS,
|
||||
"Gets the extension descriptor for the given number." },
|
||||
{ "FindAllExtensions", (PyCFunction)FindAllExtensions, METH_O,
|
||||
{ "FindAllExtensions", FindAllExtensions, METH_O,
|
||||
"Gets all known extensions of the given message descriptor." },
|
||||
{NULL}
|
||||
};
|
||||
@ -590,7 +620,7 @@ PyTypeObject PyDescriptorPool_Type = {
|
||||
FULL_MODULE_NAME ".DescriptorPool", // tp_name
|
||||
sizeof(PyDescriptorPool), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor)cdescriptor_pool::Dealloc, // tp_dealloc
|
||||
cdescriptor_pool::Dealloc, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
|
@ -33,9 +33,6 @@
|
||||
|
||||
#include <google/protobuf/pyext/extension_dict.h>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
@ -37,9 +37,8 @@
|
||||
#include <Python.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/pyext/message.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -47,16 +46,8 @@ namespace protobuf {
|
||||
class Message;
|
||||
class FieldDescriptor;
|
||||
|
||||
#ifdef _SHARED_PTR_H
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using internal::shared_ptr;
|
||||
#endif
|
||||
|
||||
namespace python {
|
||||
|
||||
struct CMessage;
|
||||
|
||||
typedef struct ExtensionDict {
|
||||
PyObject_HEAD;
|
||||
|
||||
@ -64,7 +55,7 @@ typedef struct ExtensionDict {
|
||||
// proto tree. Every Python container class holds a
|
||||
// reference to it in order to keep it alive as long as there's a
|
||||
// Python object that references any part of the tree.
|
||||
shared_ptr<Message> owner;
|
||||
CMessage::OwnerRef owner;
|
||||
|
||||
// Weak reference to parent message. Used to make sure
|
||||
// the parent is writable when an extension field is modified.
|
||||
|
@ -33,9 +33,6 @@
|
||||
#include <google/protobuf/pyext/map_container.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
@ -76,7 +73,7 @@ class MapReflectionFriend {
|
||||
struct MapIterator {
|
||||
PyObject_HEAD;
|
||||
|
||||
google::protobuf::scoped_ptr< ::google::protobuf::MapIterator> iter;
|
||||
std::unique_ptr<::google::protobuf::MapIterator> iter;
|
||||
|
||||
// A pointer back to the container, so we can notice changes to the version.
|
||||
// We own a ref on this.
|
||||
@ -94,7 +91,7 @@ struct MapIterator {
|
||||
// as this iterator does. This is solely for the benefit of the MapIterator
|
||||
// destructor -- we should never actually access the iterator in this state
|
||||
// except to delete it.
|
||||
shared_ptr<Message> owner;
|
||||
CMessage::OwnerRef owner;
|
||||
|
||||
// The version of the map when we took the iterator to it.
|
||||
//
|
||||
@ -339,6 +336,24 @@ PyObject* GetEntryClass(PyObject* _self) {
|
||||
return reinterpret_cast<PyObject*>(message_class);
|
||||
}
|
||||
|
||||
PyObject* MergeFrom(PyObject* _self, PyObject* arg) {
|
||||
MapContainer* self = GetMap(_self);
|
||||
MapContainer* other_map = GetMap(arg);
|
||||
Message* message = self->GetMutableMessage();
|
||||
const Message* other_message = other_map->message;
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
const Reflection* other_reflection = other_message->GetReflection();
|
||||
int count = other_reflection->FieldSize(
|
||||
*other_message, other_map->parent_field_descriptor);
|
||||
for (int i = 0 ; i < count; i ++) {
|
||||
reflection->AddMessage(message, self->parent_field_descriptor)->MergeFrom(
|
||||
other_reflection->GetRepeatedMessage(
|
||||
*other_message, other_map->parent_field_descriptor, i));
|
||||
}
|
||||
self->version++;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) {
|
||||
MapContainer* self = GetMap(_self);
|
||||
|
||||
@ -535,6 +550,8 @@ static PyMethodDef ScalarMapMethods[] = {
|
||||
"Gets the value for the given key if present, or otherwise a default" },
|
||||
{ "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
||||
"Return the class used to build Entries of (key, value) pairs." },
|
||||
{ "MergeFrom", (PyCFunction)MergeFrom, METH_O,
|
||||
"Merges a map into the current map." },
|
||||
/*
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
@ -810,6 +827,8 @@ static PyMethodDef MessageMapMethods[] = {
|
||||
"Alias for getitem, useful to make explicit that the map is mutated." },
|
||||
{ "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
||||
"Return the class used to build Entries of (key, value) pairs." },
|
||||
{ "MergeFrom", (PyCFunction)MergeFrom, METH_O,
|
||||
"Merges a map into the current map." },
|
||||
/*
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
|
@ -34,27 +34,18 @@
|
||||
#include <Python.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/pyext/message.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
class Message;
|
||||
|
||||
#ifdef _SHARED_PTR_H
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using internal::shared_ptr;
|
||||
#endif
|
||||
|
||||
namespace python {
|
||||
|
||||
struct CMessage;
|
||||
struct CMessageClass;
|
||||
|
||||
// This struct is used directly for ScalarMap, and is the base class of
|
||||
@ -66,7 +57,7 @@ struct MapContainer {
|
||||
// proto tree. Every Python MapContainer holds a
|
||||
// reference to it in order to keep it alive as long as there's a
|
||||
// Python object that references any part of the tree.
|
||||
shared_ptr<Message> owner;
|
||||
CMessage::OwnerRef owner;
|
||||
|
||||
// Pointer to the C++ Message that contains this container. The
|
||||
// MapContainer does not own this pointer.
|
||||
@ -99,9 +90,7 @@ struct MapContainer {
|
||||
int Release();
|
||||
|
||||
// Set the owner field of self and any children of self.
|
||||
void SetOwner(const shared_ptr<Message>& new_owner) {
|
||||
owner = new_owner;
|
||||
}
|
||||
void SetOwner(const CMessage::OwnerRef& new_owner) { owner = new_owner; }
|
||||
};
|
||||
|
||||
struct MessageMapContainer : public MapContainer {
|
||||
|
@ -35,9 +35,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <structmember.h> // A Python header file.
|
||||
@ -658,7 +655,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) {
|
||||
// Unlike PyLong_AsLongLong, PyLong_AsUnsignedLongLong is very
|
||||
// picky about the exact type.
|
||||
PyObject* casted = PyNumber_Long(arg);
|
||||
if (GOOGLE_PREDICT_FALSE(casted == NULL)) {
|
||||
if (GOOGLE_PREDICT_FALSE(casted == nullptr)) {
|
||||
// Propagate existing error.
|
||||
return false;
|
||||
}
|
||||
@ -683,7 +680,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) {
|
||||
// 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)) {
|
||||
if (GOOGLE_PREDICT_FALSE(casted == nullptr)) {
|
||||
// Propagate existing error.
|
||||
return false;
|
||||
}
|
||||
@ -830,7 +827,8 @@ bool CheckAndSetString(
|
||||
return true;
|
||||
}
|
||||
|
||||
PyObject* ToStringObject(const FieldDescriptor* descriptor, string value) {
|
||||
PyObject* ToStringObject(const FieldDescriptor* descriptor,
|
||||
const string& value) {
|
||||
if (descriptor->type() != FieldDescriptor::TYPE_STRING) {
|
||||
return PyBytes_FromStringAndSize(value.c_str(), value.length());
|
||||
}
|
||||
@ -1318,6 +1316,8 @@ CMessage* NewEmptyMessage(CMessageClass* type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Use "placement new" syntax to initialize the C++ object.
|
||||
new (&self->owner) CMessage::OwnerRef(NULL);
|
||||
self->message = NULL;
|
||||
self->parent = NULL;
|
||||
self->parent_field_descriptor = NULL;
|
||||
@ -1414,7 +1414,7 @@ static void Dealloc(CMessage* self) {
|
||||
|
||||
Py_CLEAR(self->extensions);
|
||||
Py_CLEAR(self->composite_fields);
|
||||
self->owner.reset();
|
||||
self->owner.~ThreadUnsafeSharedPtr<Message>();
|
||||
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
||||
}
|
||||
|
||||
@ -1616,9 +1616,10 @@ PyObject* HasExtension(CMessage* self, PyObject* extension) {
|
||||
// * Clear the weak references from the released container to the
|
||||
// parent.
|
||||
|
||||
struct SetOwnerVisitor : public ChildVisitor {
|
||||
class SetOwnerVisitor : public ChildVisitor {
|
||||
public:
|
||||
// new_owner must outlive this object.
|
||||
explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner)
|
||||
explicit SetOwnerVisitor(const CMessage::OwnerRef& new_owner)
|
||||
: new_owner_(new_owner) {}
|
||||
|
||||
int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
|
||||
@ -1642,11 +1643,11 @@ struct SetOwnerVisitor : public ChildVisitor {
|
||||
}
|
||||
|
||||
private:
|
||||
const shared_ptr<Message>& new_owner_;
|
||||
const CMessage::OwnerRef& new_owner_;
|
||||
};
|
||||
|
||||
// Change the owner of this CMessage and all its children, recursively.
|
||||
int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) {
|
||||
int SetOwner(CMessage* self, const CMessage::OwnerRef& new_owner) {
|
||||
self->owner = new_owner;
|
||||
if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1)
|
||||
return -1;
|
||||
@ -1679,7 +1680,7 @@ int ReleaseSubMessage(CMessage* self,
|
||||
const FieldDescriptor* field_descriptor,
|
||||
CMessage* child_cmessage) {
|
||||
// Release the Message
|
||||
shared_ptr<Message> released_message(ReleaseMessage(
|
||||
CMessage::OwnerRef released_message(ReleaseMessage(
|
||||
self, child_cmessage->message->GetDescriptor(), field_descriptor));
|
||||
child_cmessage->message = released_message.get();
|
||||
child_cmessage->owner.swap(released_message);
|
||||
@ -2329,7 +2330,9 @@ PyObject* InternalGetScalar(const Message* message,
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::CPPTYPE_STRING: {
|
||||
string value = reflection->GetString(*message, field_descriptor);
|
||||
string scratch;
|
||||
const string& value =
|
||||
reflection->GetStringReference(*message, field_descriptor, &scratch);
|
||||
result = ToStringObject(field_descriptor, value);
|
||||
break;
|
||||
}
|
||||
|
@ -37,11 +37,11 @@
|
||||
#include <Python.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/pyext/thread_unsafe_shared_ptr.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
@ -71,7 +71,9 @@ typedef struct CMessage {
|
||||
// proto tree. Every Python CMessage holds a reference to it in
|
||||
// order to keep it alive as long as there's a Python object that
|
||||
// references any part of the tree.
|
||||
shared_ptr<Message> owner;
|
||||
|
||||
typedef ThreadUnsafeSharedPtr<Message> OwnerRef;
|
||||
OwnerRef owner;
|
||||
|
||||
// Weak reference to a parent CMessage object. This is NULL for any top-level
|
||||
// message and is set for any child message (i.e. a child submessage or a
|
||||
@ -255,7 +257,7 @@ PyObject* FindInitializationErrors(CMessage* self);
|
||||
// Set the owner field of self and any children of self, recursively.
|
||||
// Used when self is being released and thus has a new owner (the
|
||||
// released Message.)
|
||||
int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner);
|
||||
int SetOwner(CMessage* self, const CMessage::OwnerRef& new_owner);
|
||||
|
||||
int AssureWritable(CMessage* self);
|
||||
|
||||
@ -336,7 +338,8 @@ bool CheckAndSetString(
|
||||
const Reflection* reflection,
|
||||
bool append,
|
||||
int index);
|
||||
PyObject* ToStringObject(const FieldDescriptor* descriptor, string value);
|
||||
PyObject* ToStringObject(const FieldDescriptor* descriptor,
|
||||
const string& value);
|
||||
|
||||
// Check if the passed field descriptor belongs to the given message.
|
||||
// If not, return false and set a Python exception (a KeyError)
|
||||
@ -347,6 +350,15 @@ extern PyObject* PickleError_class;
|
||||
|
||||
bool InitProto2MessageModule(PyObject *m);
|
||||
|
||||
#if LANG_CXX11
|
||||
// These are referenced by repeated_scalar_container, and must
|
||||
// be explicitly instantiated.
|
||||
extern template bool CheckAndGetInteger<int32>(PyObject*, int32*);
|
||||
extern template bool CheckAndGetInteger<int64>(PyObject*, int64*);
|
||||
extern template bool CheckAndGetInteger<uint32>(PyObject*, uint32*);
|
||||
extern template bool CheckAndGetInteger<uint64>(PyObject*, uint64*);
|
||||
#endif
|
||||
|
||||
} // namespace python
|
||||
} // namespace protobuf
|
||||
|
||||
|
@ -100,7 +100,9 @@ PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
|
||||
NewMessageFactory(type, reinterpret_cast<PyDescriptorPool*>(pool)));
|
||||
}
|
||||
|
||||
static void Dealloc(PyMessageFactory* self) {
|
||||
static void Dealloc(PyObject* pself) {
|
||||
PyMessageFactory* self = reinterpret_cast<PyMessageFactory*>(pself);
|
||||
|
||||
// TODO(amauryfa): When the MessageFactory is not created from the
|
||||
// DescriptorPool this reference should be owned, not borrowed.
|
||||
// Py_CLEAR(self->pool);
|
||||
@ -111,7 +113,7 @@ static void Dealloc(PyMessageFactory* self) {
|
||||
}
|
||||
delete self->classes_by_descriptor;
|
||||
delete self->message_factory;
|
||||
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
||||
Py_TYPE(self)->tp_free(pself);
|
||||
}
|
||||
|
||||
// Add a message class to our database.
|
||||
@ -231,7 +233,7 @@ PyTypeObject PyMessageFactory_Type = {
|
||||
".MessageFactory", // tp_name
|
||||
sizeof(PyMessageFactory), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor)message_factory::Dealloc, // tp_dealloc
|
||||
message_factory::Dealloc, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
|
@ -34,9 +34,6 @@
|
||||
#include <google/protobuf/pyext/repeated_composite_container.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
@ -81,7 +78,10 @@ namespace repeated_composite_container {
|
||||
// ---------------------------------------------------------------------
|
||||
// len()
|
||||
|
||||
static Py_ssize_t Length(RepeatedCompositeContainer* self) {
|
||||
static Py_ssize_t Length(PyObject* pself) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
Message* message = self->message;
|
||||
if (message != NULL) {
|
||||
return message->GetReflection()->FieldSize(*message,
|
||||
@ -102,7 +102,7 @@ static int UpdateChildMessages(RepeatedCompositeContainer* self) {
|
||||
// A MergeFrom on a parent message could have caused extra messages to be
|
||||
// added in the underlying protobuf so add them to our list. They can never
|
||||
// be removed in such a way so there's no need to worry about that.
|
||||
Py_ssize_t message_length = Length(self);
|
||||
Py_ssize_t message_length = Length(reinterpret_cast<PyObject*>(self));
|
||||
Py_ssize_t child_length = PyList_GET_SIZE(self->child_messages);
|
||||
Message* message = self->message;
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
@ -191,6 +191,10 @@ PyObject* Add(RepeatedCompositeContainer* self,
|
||||
return AddToAttached(self, args, kwargs);
|
||||
}
|
||||
|
||||
static PyObject* AddMethod(PyObject* self, PyObject* args, PyObject* kwargs) {
|
||||
return Add(reinterpret_cast<RepeatedCompositeContainer*>(self), args, kwargs);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// extend()
|
||||
|
||||
@ -226,6 +230,10 @@ PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* ExtendMethod(PyObject* self, PyObject* value) {
|
||||
return Extend(reinterpret_cast<RepeatedCompositeContainer*>(self), value);
|
||||
}
|
||||
|
||||
PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) {
|
||||
if (UpdateChildMessages(self) < 0) {
|
||||
return NULL;
|
||||
@ -233,6 +241,10 @@ PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) {
|
||||
return Extend(self, other);
|
||||
}
|
||||
|
||||
static PyObject* MergeFromMethod(PyObject* self, PyObject* other) {
|
||||
return MergeFrom(reinterpret_cast<RepeatedCompositeContainer*>(self), other);
|
||||
}
|
||||
|
||||
PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) {
|
||||
if (UpdateChildMessages(self) < 0) {
|
||||
return NULL;
|
||||
@ -242,6 +254,10 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) {
|
||||
return PyObject_GetItem(self->child_messages, slice);
|
||||
}
|
||||
|
||||
static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) {
|
||||
return Subscript(reinterpret_cast<RepeatedCompositeContainer*>(self), slice);
|
||||
}
|
||||
|
||||
int AssignSubscript(RepeatedCompositeContainer* self,
|
||||
PyObject* slice,
|
||||
PyObject* value) {
|
||||
@ -265,7 +281,7 @@ int AssignSubscript(RepeatedCompositeContainer* self,
|
||||
Py_ssize_t from;
|
||||
Py_ssize_t to;
|
||||
Py_ssize_t step;
|
||||
Py_ssize_t length = Length(self);
|
||||
Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self));
|
||||
Py_ssize_t slicelength;
|
||||
if (PySlice_Check(slice)) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
@ -290,7 +306,16 @@ int AssignSubscript(RepeatedCompositeContainer* self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) {
|
||||
static int AssignSubscriptMethod(PyObject* self, PyObject* slice,
|
||||
PyObject* value) {
|
||||
return AssignSubscript(reinterpret_cast<RepeatedCompositeContainer*>(self),
|
||||
slice, value);
|
||||
}
|
||||
|
||||
static PyObject* Remove(PyObject* pself, PyObject* value) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
if (UpdateChildMessages(self) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -305,9 +330,10 @@ static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* RichCompare(RepeatedCompositeContainer* self,
|
||||
PyObject* other,
|
||||
int opid) {
|
||||
static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
if (UpdateChildMessages(self) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -340,12 +366,13 @@ static PyObject* RichCompare(RepeatedCompositeContainer* self,
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* ToStr(RepeatedCompositeContainer* self) {
|
||||
static PyObject* ToStr(PyObject* pself) {
|
||||
ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
|
||||
if (full_slice == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
|
||||
ScopedPyObjectPtr list(Subscript(
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself), full_slice.get()));
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -359,7 +386,7 @@ static void ReorderAttached(RepeatedCompositeContainer* self) {
|
||||
Message* message = self->message;
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
const FieldDescriptor* descriptor = self->parent_field_descriptor;
|
||||
const Py_ssize_t length = Length(self);
|
||||
const Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self));
|
||||
|
||||
// Since Python protobuf objects are never arena-allocated, adding and
|
||||
// removing message pointers to the underlying array is just updating
|
||||
@ -390,9 +417,10 @@ static int SortPythonMessages(RepeatedCompositeContainer* self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject* Sort(RepeatedCompositeContainer* self,
|
||||
PyObject* args,
|
||||
PyObject* kwds) {
|
||||
static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
// Support the old sort_function argument for backwards
|
||||
// compatibility.
|
||||
if (kwds != NULL) {
|
||||
@ -416,11 +444,14 @@ static PyObject* Sort(RepeatedCompositeContainer* self,
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) {
|
||||
static PyObject* Item(PyObject* pself, Py_ssize_t index) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
if (UpdateChildMessages(self) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
Py_ssize_t length = Length(self);
|
||||
Py_ssize_t length = Length(pself);
|
||||
if (index < 0) {
|
||||
index = length + index;
|
||||
}
|
||||
@ -432,17 +463,17 @@ static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) {
|
||||
return item;
|
||||
}
|
||||
|
||||
static PyObject* Pop(RepeatedCompositeContainer* self,
|
||||
PyObject* args) {
|
||||
static PyObject* Pop(PyObject* pself, PyObject* args) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
Py_ssize_t index = -1;
|
||||
if (!PyArg_ParseTuple(args, "|n", &index)) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject* item = Item(self, index);
|
||||
PyObject* item = Item(pself, index);
|
||||
if (item == NULL) {
|
||||
PyErr_Format(PyExc_IndexError,
|
||||
"list index (%zd) out of range",
|
||||
index);
|
||||
PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr py_index(PyLong_FromSsize_t(index));
|
||||
@ -460,7 +491,7 @@ void ReleaseLastTo(CMessage* parent,
|
||||
GOOGLE_CHECK_NOTNULL(field);
|
||||
GOOGLE_CHECK_NOTNULL(target);
|
||||
|
||||
shared_ptr<Message> released_message(
|
||||
CMessage::OwnerRef released_message(
|
||||
parent->message->GetReflection()->ReleaseLast(parent->message, field));
|
||||
// TODO(tibell): Deal with proto1.
|
||||
|
||||
@ -503,7 +534,10 @@ int Release(RepeatedCompositeContainer* self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* DeepCopy(RepeatedCompositeContainer* self, PyObject* arg) {
|
||||
PyObject* DeepCopy(PyObject* pself, PyObject* arg) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
ScopedPyObjectPtr cloneObj(
|
||||
PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0));
|
||||
if (cloneObj == NULL) {
|
||||
@ -530,7 +564,7 @@ PyObject* DeepCopy(RepeatedCompositeContainer* self, PyObject* arg) {
|
||||
}
|
||||
|
||||
int SetOwner(RepeatedCompositeContainer* self,
|
||||
const shared_ptr<Message>& new_owner) {
|
||||
const CMessage::OwnerRef& new_owner) {
|
||||
GOOGLE_CHECK_ATTACHED(self);
|
||||
|
||||
self->owner = new_owner;
|
||||
@ -571,43 +605,46 @@ PyObject *NewContainer(
|
||||
return reinterpret_cast<PyObject*>(self);
|
||||
}
|
||||
|
||||
static void Dealloc(RepeatedCompositeContainer* self) {
|
||||
static void Dealloc(PyObject* pself) {
|
||||
RepeatedCompositeContainer* self =
|
||||
reinterpret_cast<RepeatedCompositeContainer*>(pself);
|
||||
|
||||
Py_CLEAR(self->child_messages);
|
||||
Py_CLEAR(self->child_message_class);
|
||||
// TODO(tibell): Do we need to call delete on these objects to make
|
||||
// sure their destructors are called?
|
||||
self->owner.reset();
|
||||
|
||||
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
||||
Py_TYPE(self)->tp_free(pself);
|
||||
}
|
||||
|
||||
static PySequenceMethods SqMethods = {
|
||||
(lenfunc)Length, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
(ssizeargfunc)Item /* sq_item */
|
||||
Length, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
Item /* sq_item */
|
||||
};
|
||||
|
||||
static PyMappingMethods MpMethods = {
|
||||
(lenfunc)Length, /* mp_length */
|
||||
(binaryfunc)Subscript, /* mp_subscript */
|
||||
(objobjargproc)AssignSubscript,/* mp_ass_subscript */
|
||||
Length, /* mp_length */
|
||||
SubscriptMethod, /* mp_subscript */
|
||||
AssignSubscriptMethod, /* mp_ass_subscript */
|
||||
};
|
||||
|
||||
static PyMethodDef Methods[] = {
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
{ "__deepcopy__", DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
{ "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
|
||||
{ "add", (PyCFunction)AddMethod, METH_VARARGS | METH_KEYWORDS,
|
||||
"Adds an object to the repeated container." },
|
||||
{ "extend", (PyCFunction) Extend, METH_O,
|
||||
{ "extend", ExtendMethod, METH_O,
|
||||
"Adds objects to the repeated container." },
|
||||
{ "pop", (PyCFunction)Pop, METH_VARARGS,
|
||||
{ "pop", Pop, METH_VARARGS,
|
||||
"Removes an object from the repeated container and returns it." },
|
||||
{ "remove", (PyCFunction) Remove, METH_O,
|
||||
{ "remove", Remove, METH_O,
|
||||
"Removes an object from the repeated container." },
|
||||
{ "sort", (PyCFunction) Sort, METH_VARARGS | METH_KEYWORDS,
|
||||
{ "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
|
||||
"Sorts the repeated container." },
|
||||
{ "MergeFrom", (PyCFunction) MergeFrom, METH_O,
|
||||
{ "MergeFrom", MergeFromMethod, METH_O,
|
||||
"Adds objects to the repeated container." },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
@ -619,12 +656,12 @@ PyTypeObject RepeatedCompositeContainer_Type = {
|
||||
FULL_MODULE_NAME ".RepeatedCompositeContainer", // tp_name
|
||||
sizeof(RepeatedCompositeContainer), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor)repeated_composite_container::Dealloc, // tp_dealloc
|
||||
repeated_composite_container::Dealloc, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc)repeated_composite_container::ToStr, // tp_repr
|
||||
repeated_composite_container::ToStr, // tp_repr
|
||||
0, // tp_as_number
|
||||
&repeated_composite_container::SqMethods, // tp_as_sequence
|
||||
&repeated_composite_container::MpMethods, // tp_as_mapping
|
||||
@ -638,7 +675,7 @@ PyTypeObject RepeatedCompositeContainer_Type = {
|
||||
"A Repeated scalar container", // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
(richcmpfunc)repeated_composite_container::RichCompare, // tp_richcompare
|
||||
repeated_composite_container::RichCompare, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
|
@ -37,27 +37,19 @@
|
||||
#include <Python.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/pyext/message.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
class FieldDescriptor;
|
||||
class Message;
|
||||
|
||||
#ifdef _SHARED_PTR_H
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using internal::shared_ptr;
|
||||
#endif
|
||||
|
||||
namespace python {
|
||||
|
||||
struct CMessage;
|
||||
struct CMessageClass;
|
||||
|
||||
// A RepeatedCompositeContainer can be in one of two states: attached
|
||||
@ -77,7 +69,7 @@ typedef struct RepeatedCompositeContainer {
|
||||
// proto tree. Every Python RepeatedCompositeContainer holds a
|
||||
// reference to it in order to keep it alive as long as there's a
|
||||
// Python object that references any part of the tree.
|
||||
shared_ptr<Message> owner;
|
||||
CMessage::OwnerRef owner;
|
||||
|
||||
// Weak reference to parent object. May be NULL. Used to make sure
|
||||
// the parent is writable before modifying the
|
||||
@ -148,11 +140,6 @@ int AssignSubscript(RepeatedCompositeContainer* self,
|
||||
PyObject* slice,
|
||||
PyObject* value);
|
||||
|
||||
// Releases the messages in the container to the given message.
|
||||
//
|
||||
// Returns 0 on success, -1 on failure.
|
||||
int ReleaseToMessage(RepeatedCompositeContainer* self, Message* new_message);
|
||||
|
||||
// Releases the messages in the container to a new message.
|
||||
//
|
||||
// Returns 0 on success, -1 on failure.
|
||||
@ -160,7 +147,7 @@ int Release(RepeatedCompositeContainer* self);
|
||||
|
||||
// Returns 0 on success, -1 on failure.
|
||||
int SetOwner(RepeatedCompositeContainer* self,
|
||||
const shared_ptr<Message>& new_owner);
|
||||
const CMessage::OwnerRef& new_owner);
|
||||
|
||||
// Removes the last element of the repeated message field 'field' on
|
||||
// the Message 'parent', and transfers the ownership of the released
|
||||
|
@ -34,9 +34,6 @@
|
||||
#include <google/protobuf/pyext/repeated_scalar_container.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
@ -77,15 +74,18 @@ static int InternalAssignRepeatedField(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Py_ssize_t Len(RepeatedScalarContainer* self) {
|
||||
static Py_ssize_t Len(PyObject* pself) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
Message* message = self->message;
|
||||
return message->GetReflection()->FieldSize(*message,
|
||||
self->parent_field_descriptor);
|
||||
}
|
||||
|
||||
static int AssignItem(RepeatedScalarContainer* self,
|
||||
Py_ssize_t index,
|
||||
PyObject* arg) {
|
||||
static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
cmessage::AssureWritable(self->parent);
|
||||
Message* message = self->message;
|
||||
const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
|
||||
@ -188,7 +188,10 @@ static int AssignItem(RepeatedScalarContainer* self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) {
|
||||
static PyObject* Item(PyObject* pself, Py_ssize_t index) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
Message* message = self->message;
|
||||
const FieldDescriptor* field_descriptor = self->parent_field_descriptor;
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
@ -256,8 +259,9 @@ static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) {
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::CPPTYPE_STRING: {
|
||||
string value = reflection->GetRepeatedString(
|
||||
*message, field_descriptor, index);
|
||||
string scratch;
|
||||
const string& value = reflection->GetRepeatedStringReference(
|
||||
*message, field_descriptor, index, &scratch);
|
||||
result = ToStringObject(field_descriptor, value);
|
||||
break;
|
||||
}
|
||||
@ -271,7 +275,10 @@ static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
|
||||
static PyObject* Subscript(PyObject* pself, PyObject* slice) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
Py_ssize_t from;
|
||||
Py_ssize_t to;
|
||||
Py_ssize_t step;
|
||||
@ -286,14 +293,13 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
|
||||
if (PyLong_Check(slice)) {
|
||||
from = to = PyLong_AsLong(slice);
|
||||
} else if (PySlice_Check(slice)) {
|
||||
length = Len(self);
|
||||
length = Len(pself);
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (PySlice_GetIndicesEx(slice,
|
||||
length, &from, &to, &step, &slicelength) == -1) {
|
||||
#else
|
||||
if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
|
||||
length, &from, &to, &step, &slicelength) == -1) {
|
||||
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
@ -304,7 +310,7 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
|
||||
}
|
||||
|
||||
if (!return_list) {
|
||||
return Item(self, from);
|
||||
return Item(pself, from);
|
||||
}
|
||||
|
||||
PyObject* list = PyList_New(0);
|
||||
@ -319,7 +325,7 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
|
||||
if (index < 0 || index >= length) {
|
||||
break;
|
||||
}
|
||||
ScopedPyObjectPtr s(Item(self, index));
|
||||
ScopedPyObjectPtr s(Item(pself, index));
|
||||
PyList_Append(list, s.get());
|
||||
}
|
||||
} else {
|
||||
@ -330,7 +336,7 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
|
||||
if (index < 0 || index >= length) {
|
||||
break;
|
||||
}
|
||||
ScopedPyObjectPtr s(Item(self, index));
|
||||
ScopedPyObjectPtr s(Item(pself, index));
|
||||
PyList_Append(list, s.get());
|
||||
}
|
||||
}
|
||||
@ -417,9 +423,14 @@ PyObject* Append(RepeatedScalarContainer* self, PyObject* item) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int AssSubscript(RepeatedScalarContainer* self,
|
||||
PyObject* slice,
|
||||
PyObject* value) {
|
||||
static PyObject* AppendMethod(PyObject* self, PyObject* item) {
|
||||
return Append(reinterpret_cast<RepeatedScalarContainer*>(self), item);
|
||||
}
|
||||
|
||||
static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
Py_ssize_t from;
|
||||
Py_ssize_t to;
|
||||
Py_ssize_t step;
|
||||
@ -435,7 +446,7 @@ static int AssSubscript(RepeatedScalarContainer* self,
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check(slice)) {
|
||||
from = to = PyInt_AsLong(slice);
|
||||
} else
|
||||
} else // NOLINT
|
||||
#endif
|
||||
if (PyLong_Check(slice)) {
|
||||
from = to = PyLong_AsLong(slice);
|
||||
@ -463,14 +474,14 @@ static int AssSubscript(RepeatedScalarContainer* self,
|
||||
}
|
||||
|
||||
if (!create_list) {
|
||||
return AssignItem(self, from, value);
|
||||
return AssignItem(pself, from, value);
|
||||
}
|
||||
|
||||
ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
|
||||
if (full_slice == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ScopedPyObjectPtr new_list(Subscript(self, full_slice.get()));
|
||||
ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get()));
|
||||
if (new_list == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@ -509,14 +520,17 @@ PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) {
|
||||
static PyObject* Insert(PyObject* pself, PyObject* args) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
Py_ssize_t index;
|
||||
PyObject* value;
|
||||
if (!PyArg_ParseTuple(args, "lO", &index, &value)) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
|
||||
ScopedPyObjectPtr new_list(Subscript(self, full_slice.get()));
|
||||
ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get()));
|
||||
if (PyList_Insert(new_list.get(), index, value) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -527,10 +541,13 @@ static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) {
|
||||
static PyObject* Remove(PyObject* pself, PyObject* value) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
Py_ssize_t match_index = -1;
|
||||
for (Py_ssize_t i = 0; i < Len(self); ++i) {
|
||||
ScopedPyObjectPtr elem(Item(self, i));
|
||||
for (Py_ssize_t i = 0; i < Len(pself); ++i) {
|
||||
ScopedPyObjectPtr elem(Item(pself, i));
|
||||
if (PyObject_RichCompareBool(elem.get(), value, Py_EQ)) {
|
||||
match_index = i;
|
||||
break;
|
||||
@ -540,15 +557,20 @@ static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) {
|
||||
PyErr_SetString(PyExc_ValueError, "remove(x): x not in container");
|
||||
return NULL;
|
||||
}
|
||||
if (AssignItem(self, match_index, NULL) < 0) {
|
||||
if (AssignItem(pself, match_index, NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* RichCompare(RepeatedScalarContainer* self,
|
||||
PyObject* other,
|
||||
int opid) {
|
||||
static PyObject* ExtendMethod(PyObject* self, PyObject* value) {
|
||||
return Extend(reinterpret_cast<RepeatedScalarContainer*>(self), value);
|
||||
}
|
||||
|
||||
static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
if (opid != Py_EQ && opid != Py_NE) {
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
@ -565,28 +587,25 @@ static PyObject* RichCompare(RepeatedScalarContainer* self,
|
||||
|
||||
ScopedPyObjectPtr other_list_deleter;
|
||||
if (PyObject_TypeCheck(other, &RepeatedScalarContainer_Type)) {
|
||||
other_list_deleter.reset(Subscript(
|
||||
reinterpret_cast<RepeatedScalarContainer*>(other), full_slice.get()));
|
||||
other_list_deleter.reset(Subscript(other, full_slice.get()));
|
||||
other = other_list_deleter.get();
|
||||
}
|
||||
|
||||
ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
|
||||
ScopedPyObjectPtr list(Subscript(pself, full_slice.get()));
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return PyObject_RichCompare(list.get(), other, opid);
|
||||
}
|
||||
|
||||
PyObject* Reduce(RepeatedScalarContainer* unused_self) {
|
||||
PyObject* Reduce(PyObject* unused_self, PyObject* unused_other) {
|
||||
PyErr_Format(
|
||||
PickleError_class,
|
||||
"can't pickle repeated message fields, convert to list first");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject* Sort(RepeatedScalarContainer* self,
|
||||
PyObject* args,
|
||||
PyObject* kwds) {
|
||||
static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) {
|
||||
// Support the old sort_function argument for backwards
|
||||
// compatibility.
|
||||
if (kwds != NULL) {
|
||||
@ -605,7 +624,7 @@ static PyObject* Sort(RepeatedScalarContainer* self,
|
||||
if (full_slice == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
|
||||
ScopedPyObjectPtr list(Subscript(pself, full_slice.get()));
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -617,38 +636,39 @@ static PyObject* Sort(RepeatedScalarContainer* self,
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
int ret = InternalAssignRepeatedField(self, list.get());
|
||||
int ret = InternalAssignRepeatedField(
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself), list.get());
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* Pop(RepeatedScalarContainer* self,
|
||||
PyObject* args) {
|
||||
static PyObject* Pop(PyObject* pself, PyObject* args) {
|
||||
Py_ssize_t index = -1;
|
||||
if (!PyArg_ParseTuple(args, "|n", &index)) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject* item = Item(self, index);
|
||||
PyObject* item = Item(pself, index);
|
||||
if (item == NULL) {
|
||||
PyErr_Format(PyExc_IndexError,
|
||||
"list index (%zd) out of range",
|
||||
index);
|
||||
PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
|
||||
return NULL;
|
||||
}
|
||||
if (AssignItem(self, index, NULL) < 0) {
|
||||
if (AssignItem(pself, index, NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
static PyObject* ToStr(RepeatedScalarContainer* self) {
|
||||
static PyObject* ToStr(PyObject* pself) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
|
||||
if (full_slice == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
|
||||
ScopedPyObjectPtr list(Subscript(pself, full_slice.get()));
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -687,7 +707,8 @@ static int InitializeAndCopyToParentContainer(
|
||||
if (full_slice == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ScopedPyObjectPtr values(Subscript(from, full_slice.get()));
|
||||
ScopedPyObjectPtr values(
|
||||
Subscript(reinterpret_cast<PyObject*>(from), full_slice.get()));
|
||||
if (values == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@ -706,7 +727,10 @@ int Release(RepeatedScalarContainer* self) {
|
||||
return InitializeAndCopyToParentContainer(self, self);
|
||||
}
|
||||
|
||||
PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) {
|
||||
PyObject* DeepCopy(PyObject* pself, PyObject* arg) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
|
||||
RepeatedScalarContainer* clone = reinterpret_cast<RepeatedScalarContainer*>(
|
||||
PyType_GenericAlloc(&RepeatedScalarContainer_Type, 0));
|
||||
if (clone == NULL) {
|
||||
@ -720,45 +744,47 @@ PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) {
|
||||
return reinterpret_cast<PyObject*>(clone);
|
||||
}
|
||||
|
||||
static void Dealloc(RepeatedScalarContainer* self) {
|
||||
static void Dealloc(PyObject* pself) {
|
||||
RepeatedScalarContainer* self =
|
||||
reinterpret_cast<RepeatedScalarContainer*>(pself);
|
||||
self->owner.reset();
|
||||
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
||||
Py_TYPE(self)->tp_free(pself);
|
||||
}
|
||||
|
||||
void SetOwner(RepeatedScalarContainer* self,
|
||||
const shared_ptr<Message>& new_owner) {
|
||||
const CMessage::OwnerRef& new_owner) {
|
||||
self->owner = new_owner;
|
||||
}
|
||||
|
||||
static PySequenceMethods SqMethods = {
|
||||
(lenfunc)Len, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
(ssizeargfunc)Item, /* sq_item */
|
||||
0, /* sq_slice */
|
||||
(ssizeobjargproc)AssignItem /* sq_ass_item */
|
||||
Len, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
Item, /* sq_item */
|
||||
0, /* sq_slice */
|
||||
AssignItem /* sq_ass_item */
|
||||
};
|
||||
|
||||
static PyMappingMethods MpMethods = {
|
||||
(lenfunc)Len, /* mp_length */
|
||||
(binaryfunc)Subscript, /* mp_subscript */
|
||||
(objobjargproc)AssSubscript, /* mp_ass_subscript */
|
||||
Len, /* mp_length */
|
||||
Subscript, /* mp_subscript */
|
||||
AssSubscript, /* mp_ass_subscript */
|
||||
};
|
||||
|
||||
static PyMethodDef Methods[] = {
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
{ "__deepcopy__", DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
||||
{ "__reduce__", Reduce, METH_NOARGS,
|
||||
"Outputs picklable representation of the repeated field." },
|
||||
{ "append", (PyCFunction)Append, METH_O,
|
||||
{ "append", AppendMethod, METH_O,
|
||||
"Appends an object to the repeated container." },
|
||||
{ "extend", (PyCFunction)Extend, METH_O,
|
||||
{ "extend", ExtendMethod, METH_O,
|
||||
"Appends objects to the repeated container." },
|
||||
{ "insert", (PyCFunction)Insert, METH_VARARGS,
|
||||
"Appends objects to the repeated container." },
|
||||
{ "pop", (PyCFunction)Pop, METH_VARARGS,
|
||||
{ "insert", Insert, METH_VARARGS,
|
||||
"Inserts an object at the specified position in the container." },
|
||||
{ "pop", Pop, METH_VARARGS,
|
||||
"Removes an object from the repeated container and returns it." },
|
||||
{ "remove", (PyCFunction)Remove, METH_O,
|
||||
{ "remove", Remove, METH_O,
|
||||
"Removes an object from the repeated container." },
|
||||
{ "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
|
||||
"Sorts the repeated container."},
|
||||
@ -772,12 +798,12 @@ PyTypeObject RepeatedScalarContainer_Type = {
|
||||
FULL_MODULE_NAME ".RepeatedScalarContainer", // tp_name
|
||||
sizeof(RepeatedScalarContainer), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor)repeated_scalar_container::Dealloc, // tp_dealloc
|
||||
repeated_scalar_container::Dealloc, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc)repeated_scalar_container::ToStr, // tp_repr
|
||||
repeated_scalar_container::ToStr, // tp_repr
|
||||
0, // tp_as_number
|
||||
&repeated_scalar_container::SqMethods, // tp_as_sequence
|
||||
&repeated_scalar_container::MpMethods, // tp_as_mapping
|
||||
@ -791,7 +817,7 @@ PyTypeObject RepeatedScalarContainer_Type = {
|
||||
"A Repeated scalar container", // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
(richcmpfunc)repeated_scalar_container::RichCompare, // tp_richcompare
|
||||
repeated_scalar_container::RichCompare, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
|
@ -37,27 +37,14 @@
|
||||
#include <Python.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/pyext/message.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
class Message;
|
||||
|
||||
#ifdef _SHARED_PTR_H
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using internal::shared_ptr;
|
||||
#endif
|
||||
|
||||
namespace python {
|
||||
|
||||
struct CMessage;
|
||||
|
||||
typedef struct RepeatedScalarContainer {
|
||||
PyObject_HEAD;
|
||||
|
||||
@ -65,7 +52,7 @@ typedef struct RepeatedScalarContainer {
|
||||
// proto tree. Every Python RepeatedScalarContainer holds a
|
||||
// reference to it in order to keep it alive as long as there's a
|
||||
// Python object that references any part of the tree.
|
||||
shared_ptr<Message> owner;
|
||||
CMessage::OwnerRef owner;
|
||||
|
||||
// Pointer to the C++ Message that contains this container. The
|
||||
// RepeatedScalarContainer does not own this pointer.
|
||||
@ -112,7 +99,7 @@ PyObject* Extend(RepeatedScalarContainer* self, PyObject* value);
|
||||
|
||||
// Set the owner field of self and any children of self.
|
||||
void SetOwner(RepeatedScalarContainer* self,
|
||||
const shared_ptr<Message>& new_owner);
|
||||
const CMessage::OwnerRef& new_owner);
|
||||
|
||||
} // namespace repeated_scalar_container
|
||||
} // namespace python
|
||||
|
@ -141,9 +141,11 @@ def MessageToString(message,
|
||||
as_one_line: Don't introduce newlines between fields.
|
||||
pointy_brackets: If True, use angle brackets instead of curly braces for
|
||||
nesting.
|
||||
use_index_order: If True, print fields of a proto message using the order
|
||||
defined in source code instead of the field number. By default, use the
|
||||
field number order.
|
||||
use_index_order: If True, fields of a proto message will be printed using
|
||||
the order defined in source code instead of the field number, extensions
|
||||
will be printed at the end of the message and their relative order is
|
||||
determined by the extension number. By default, use the field number
|
||||
order.
|
||||
float_format: If set, use this to specify floating point number formatting
|
||||
(per the "Format Specification Mini-Language"); otherwise, str() is used.
|
||||
use_field_number: If True, print field numbers instead of names.
|
||||
@ -336,11 +338,12 @@ class _Printer(object):
|
||||
return
|
||||
fields = message.ListFields()
|
||||
if self.use_index_order:
|
||||
fields.sort(key=lambda x: x[0].index)
|
||||
fields.sort(
|
||||
key=lambda x: x[0].number if x[0].is_extension else x[0].index)
|
||||
for field, value in fields:
|
||||
if _IsMapEntry(field):
|
||||
for key in sorted(value):
|
||||
# This is slow for maps with submessage entires because it copies the
|
||||
# This is slow for maps with submessage entries because it copies the
|
||||
# entire tree. Unfortunately this would take significant refactoring
|
||||
# of this file to work around.
|
||||
#
|
||||
@ -645,6 +648,30 @@ class _Parser(object):
|
||||
ParseError: In case of text parsing problems.
|
||||
"""
|
||||
message_descriptor = message.DESCRIPTOR
|
||||
if (message_descriptor.full_name == _ANY_FULL_TYPE_NAME and
|
||||
tokenizer.TryConsume('[')):
|
||||
type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer)
|
||||
tokenizer.Consume(']')
|
||||
tokenizer.TryConsume(':')
|
||||
if tokenizer.TryConsume('<'):
|
||||
expanded_any_end_token = '>'
|
||||
else:
|
||||
tokenizer.Consume('{')
|
||||
expanded_any_end_token = '}'
|
||||
expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name,
|
||||
self.descriptor_pool)
|
||||
if not expanded_any_sub_message:
|
||||
raise ParseError('Type %s not found in descriptor pool' %
|
||||
packed_type_name)
|
||||
while not tokenizer.TryConsume(expanded_any_end_token):
|
||||
if tokenizer.AtEnd():
|
||||
raise tokenizer.ParseErrorPreviousToken('Expected "%s".' %
|
||||
(expanded_any_end_token,))
|
||||
self._MergeField(tokenizer, expanded_any_sub_message)
|
||||
message.Pack(expanded_any_sub_message,
|
||||
type_url_prefix=type_url_prefix)
|
||||
return
|
||||
|
||||
if tokenizer.TryConsume('['):
|
||||
name = [tokenizer.ConsumeIdentifier()]
|
||||
while tokenizer.TryConsume('.'):
|
||||
@ -725,11 +752,12 @@ class _Parser(object):
|
||||
if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and
|
||||
tokenizer.TryConsume('[')):
|
||||
# Short repeated format, e.g. "foo: [1, 2, 3]"
|
||||
while True:
|
||||
merger(tokenizer, message, field)
|
||||
if tokenizer.TryConsume(']'):
|
||||
break
|
||||
tokenizer.Consume(',')
|
||||
if not tokenizer.TryConsume(']'):
|
||||
while True:
|
||||
merger(tokenizer, message, field)
|
||||
if tokenizer.TryConsume(']'):
|
||||
break
|
||||
tokenizer.Consume(',')
|
||||
|
||||
else:
|
||||
merger(tokenizer, message, field)
|
||||
@ -777,33 +805,7 @@ class _Parser(object):
|
||||
tokenizer.Consume('{')
|
||||
end_token = '}'
|
||||
|
||||
if (field.message_type.full_name == _ANY_FULL_TYPE_NAME and
|
||||
tokenizer.TryConsume('[')):
|
||||
type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer)
|
||||
tokenizer.Consume(']')
|
||||
tokenizer.TryConsume(':')
|
||||
if tokenizer.TryConsume('<'):
|
||||
expanded_any_end_token = '>'
|
||||
else:
|
||||
tokenizer.Consume('{')
|
||||
expanded_any_end_token = '}'
|
||||
expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name,
|
||||
self.descriptor_pool)
|
||||
if not expanded_any_sub_message:
|
||||
raise ParseError('Type %s not found in descriptor pool' %
|
||||
packed_type_name)
|
||||
while not tokenizer.TryConsume(expanded_any_end_token):
|
||||
if tokenizer.AtEnd():
|
||||
raise tokenizer.ParseErrorPreviousToken('Expected "%s".' %
|
||||
(expanded_any_end_token,))
|
||||
self._MergeField(tokenizer, expanded_any_sub_message)
|
||||
if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
|
||||
any_message = getattr(message, field.name).add()
|
||||
else:
|
||||
any_message = getattr(message, field.name)
|
||||
any_message.Pack(expanded_any_sub_message,
|
||||
type_url_prefix=type_url_prefix)
|
||||
elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
|
||||
if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
|
||||
if field.is_extension:
|
||||
sub_message = message.Extensions[field].add()
|
||||
elif is_map_entry:
|
||||
@ -812,8 +814,20 @@ class _Parser(object):
|
||||
sub_message = getattr(message, field.name).add()
|
||||
else:
|
||||
if field.is_extension:
|
||||
if (not self._allow_multiple_scalars and
|
||||
message.HasExtension(field)):
|
||||
raise tokenizer.ParseErrorPreviousToken(
|
||||
'Message type "%s" should not have multiple "%s" extensions.' %
|
||||
(message.DESCRIPTOR.full_name, field.full_name))
|
||||
sub_message = message.Extensions[field]
|
||||
else:
|
||||
# Also apply _allow_multiple_scalars to message field.
|
||||
# TODO(jieluo): Change to _allow_singular_overwrites.
|
||||
if (not self._allow_multiple_scalars and
|
||||
message.HasField(field.name)):
|
||||
raise tokenizer.ParseErrorPreviousToken(
|
||||
'Message type "%s" should not have multiple "%s" fields.' %
|
||||
(message.DESCRIPTOR.full_name, field.name))
|
||||
sub_message = getattr(message, field.name)
|
||||
sub_message.SetInParent()
|
||||
|
||||
|
@ -64,20 +64,6 @@ MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
|
||||
nobase_include_HEADERS = \
|
||||
google/protobuf/stubs/atomic_sequence_num.h \
|
||||
google/protobuf/stubs/atomicops.h \
|
||||
google/protobuf/stubs/atomicops_internals_power.h \
|
||||
google/protobuf/stubs/atomicops_internals_ppc_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
|
||||
google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h \
|
||||
google/protobuf/stubs/atomicops_internals_generic_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_mips_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_solaris.h \
|
||||
google/protobuf/stubs/atomicops_internals_tsan.h \
|
||||
google/protobuf/stubs/atomicops_internals_x86_gcc.h \
|
||||
google/protobuf/stubs/atomicops_internals_x86_msvc.h \
|
||||
google/protobuf/stubs/callback.h \
|
||||
google/protobuf/stubs/bytestream.h \
|
||||
google/protobuf/stubs/casts.h \
|
||||
@ -90,8 +76,6 @@ nobase_include_HEADERS = \
|
||||
google/protobuf/stubs/once.h \
|
||||
google/protobuf/stubs/platform_macros.h \
|
||||
google/protobuf/stubs/port.h \
|
||||
google/protobuf/stubs/scoped_ptr.h \
|
||||
google/protobuf/stubs/shared_ptr.h \
|
||||
google/protobuf/stubs/singleton.h \
|
||||
google/protobuf/stubs/status.h \
|
||||
google/protobuf/stubs/stl_util.h \
|
||||
@ -189,8 +173,6 @@ libprotobuf_lite_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf-lite.m
|
||||
EXTRA_libprotobuf_lite_la_DEPENDENCIES = libprotobuf-lite.map
|
||||
endif
|
||||
libprotobuf_lite_la_SOURCES = \
|
||||
google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
|
||||
google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
|
||||
google/protobuf/stubs/bytestream.cc \
|
||||
google/protobuf/stubs/bytestream.h \
|
||||
google/protobuf/stubs/common.cc \
|
||||
@ -201,8 +183,6 @@ libprotobuf_lite_la_SOURCES = \
|
||||
google/protobuf/stubs/io_win32.h \
|
||||
google/protobuf/stubs/map_util.h \
|
||||
google/protobuf/stubs/mathutil.h \
|
||||
google/protobuf/stubs/once.cc \
|
||||
google/protobuf/stubs/shared_ptr.h \
|
||||
google/protobuf/stubs/status.cc \
|
||||
google/protobuf/stubs/status.h \
|
||||
google/protobuf/stubs/status_macros.h \
|
||||
@ -772,7 +752,6 @@ protobuf_test_SOURCES = \
|
||||
google/protobuf/stubs/common_unittest.cc \
|
||||
google/protobuf/stubs/int128_unittest.cc \
|
||||
google/protobuf/stubs/io_win32_unittest.cc \
|
||||
google/protobuf/stubs/once_unittest.cc \
|
||||
google/protobuf/stubs/statusor_test.cc \
|
||||
google/protobuf/stubs/status_test.cc \
|
||||
google/protobuf/stubs/stringpiece_unittest.cc \
|
||||
@ -796,8 +775,8 @@ protobuf_test_SOURCES = \
|
||||
google/protobuf/message_unittest.cc \
|
||||
google/protobuf/no_field_presence_test.cc \
|
||||
google/protobuf/preserve_unknown_enum_test.cc \
|
||||
google/protobuf/proto3_arena_unittest.cc \
|
||||
google/protobuf/proto3_arena_lite_unittest.cc \
|
||||
google/protobuf/proto3_arena_unittest.cc \
|
||||
google/protobuf/proto3_lite_unittest.cc \
|
||||
google/protobuf/reflection_ops_unittest.cc \
|
||||
google/protobuf/repeated_field_reflection_unittest.cc \
|
||||
@ -928,9 +907,7 @@ endif
|
||||
no_warning_test.cc:
|
||||
echo "// Generated from Makefile.am" > no_warning_test.cc
|
||||
for FILE in $(nobase_include_HEADERS); do \
|
||||
if ! echo $${FILE} | grep "atomicops"; then \
|
||||
echo "#include <$${FILE}>" >> no_warning_test.cc; \
|
||||
fi \
|
||||
echo "#include <$${FILE}>" >> no_warning_test.cc; \
|
||||
done
|
||||
echo "int main(int, char**) { return 0; }" >> no_warning_test.cc
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace internal {
|
||||
@ -84,15 +85,23 @@ bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
|
||||
return full_name == descriptor->full_name();
|
||||
}
|
||||
|
||||
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
|
||||
bool ParseAnyTypeUrl(const string& type_url, string* url_prefix,
|
||||
string* full_type_name) {
|
||||
size_t pos = type_url.find_last_of("/");
|
||||
if (pos == string::npos || pos + 1 == type_url.size()) {
|
||||
return false;
|
||||
}
|
||||
if (url_prefix) {
|
||||
*url_prefix = type_url.substr(0, pos + 1);
|
||||
}
|
||||
*full_type_name = type_url.substr(pos + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
|
||||
return ParseAnyTypeUrl(type_url, NULL, full_type_name);
|
||||
}
|
||||
|
||||
|
||||
bool GetAnyFieldDescriptors(const Message& message,
|
||||
const FieldDescriptor** type_url_field,
|
||||
|
@ -92,8 +92,19 @@ extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
|
||||
// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
|
||||
// *full_type_name. Returns false if the type_url does not have a "/"
|
||||
// in the type url separating the full type name.
|
||||
//
|
||||
// NOTE: this function is available publicly as:
|
||||
// google::protobuf::Any() // static method on the generated message type.
|
||||
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
|
||||
|
||||
// Get the proto type name and prefix from Any::type_url value. For example,
|
||||
// passing "type.googleapis.com/rpc.QueryOrigin" will return
|
||||
// "type.googleapis.com/" in *url_prefix and "rpc.QueryOrigin" in
|
||||
// *full_type_name. Returns false if the type_url does not have a "/" in the
|
||||
// type url separating the full type name.
|
||||
bool ParseAnyTypeUrl(const string& type_url, string* url_prefix,
|
||||
string* full_type_name);
|
||||
|
||||
// See if message is of type google.protobuf.Any, if so, return the descriptors
|
||||
// for "type_url" and "value" fields.
|
||||
bool GetAnyFieldDescriptors(const Message& message,
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
#include <google/protobuf/stubs/once.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/wire_format_lite_inl.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
@ -19,6 +18,7 @@
|
||||
#include "third_party/protobuf/version.h"
|
||||
#endif
|
||||
// @@protoc_insertion_point(includes)
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class AnyDefaultTypeInternal {
|
||||
@ -29,14 +29,9 @@ class AnyDefaultTypeInternal {
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
namespace protobuf_google_2fprotobuf_2fany_2eproto {
|
||||
void InitDefaultsAnyImpl() {
|
||||
static void InitDefaultsAny() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
|
||||
#else
|
||||
::google::protobuf::internal::InitProtobufDefaults();
|
||||
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
{
|
||||
void* ptr = &::google::protobuf::_Any_default_instance_;
|
||||
new (ptr) ::google::protobuf::Any();
|
||||
@ -45,9 +40,11 @@ void InitDefaultsAnyImpl() {
|
||||
::google::protobuf::Any::InitAsDefaultInstance();
|
||||
}
|
||||
|
||||
void InitDefaultsAny() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsAnyImpl);
|
||||
LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Any =
|
||||
{{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAny}, {}};
|
||||
|
||||
void InitDefaults() {
|
||||
::google::protobuf::internal::InitSCC(&scc_info_Any.base);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata file_level_metadata[1];
|
||||
@ -71,15 +68,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = {
|
||||
|
||||
void protobuf_AssignDescriptors() {
|
||||
AddDescriptors();
|
||||
::google::protobuf::MessageFactory* factory = NULL;
|
||||
AssignDescriptors(
|
||||
"google/protobuf/any.proto", schemas, file_default_instances, TableStruct::offsets, factory,
|
||||
"google/protobuf/any.proto", schemas, file_default_instances, TableStruct::offsets,
|
||||
file_level_metadata, NULL, NULL);
|
||||
}
|
||||
|
||||
void protobuf_AssignDescriptorsOnce() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
|
||||
static ::google::protobuf::internal::once_flag once;
|
||||
::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
|
||||
}
|
||||
|
||||
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
|
||||
@ -105,8 +101,8 @@ void AddDescriptorsImpl() {
|
||||
}
|
||||
|
||||
void AddDescriptors() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
|
||||
static ::google::protobuf::internal::once_flag once;
|
||||
::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
|
||||
}
|
||||
// Force AddDescriptors() to be called at dynamic initialization time.
|
||||
struct StaticDescriptorInitializer {
|
||||
@ -134,6 +130,11 @@ void Any::PackFrom(const ::google::protobuf::Message& message,
|
||||
bool Any::UnpackTo(::google::protobuf::Message* message) const {
|
||||
return _any_metadata_.UnpackTo(message);
|
||||
}
|
||||
bool Any::ParseAnyTypeUrl(const string& type_url,
|
||||
string* full_type_name) {
|
||||
return ::google::protobuf::internal::ParseAnyTypeUrl(type_url,
|
||||
full_type_name);
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
const int Any::kTypeUrlFieldNumber;
|
||||
@ -142,16 +143,14 @@ const int Any::kValueFieldNumber;
|
||||
|
||||
Any::Any()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL), _any_metadata_(&type_url_, &value_) {
|
||||
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
|
||||
::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAny();
|
||||
}
|
||||
::google::protobuf::internal::InitSCC(
|
||||
&protobuf_google_2fprotobuf_2fany_2eproto::scc_info_Any.base);
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:google.protobuf.Any)
|
||||
}
|
||||
Any::Any(const Any& from)
|
||||
: ::google::protobuf::Message(),
|
||||
_internal_metadata_(NULL),
|
||||
_cached_size_(0),
|
||||
_any_metadata_(&type_url_, &value_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
@ -168,7 +167,6 @@ Any::Any(const Any& from)
|
||||
void Any::SharedCtor() {
|
||||
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
_cached_size_ = 0;
|
||||
}
|
||||
|
||||
Any::~Any() {
|
||||
@ -182,9 +180,7 @@ void Any::SharedDtor() {
|
||||
}
|
||||
|
||||
void Any::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
_cached_size_.Set(size);
|
||||
}
|
||||
const ::google::protobuf::Descriptor* Any::descriptor() {
|
||||
::protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
|
||||
@ -192,7 +188,7 @@ const ::google::protobuf::Descriptor* Any::descriptor() {
|
||||
}
|
||||
|
||||
const Any& Any::default_instance() {
|
||||
::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAny();
|
||||
::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fany_2eproto::scc_info_Any.base);
|
||||
return *internal_default_instance();
|
||||
}
|
||||
|
||||
@ -214,7 +210,7 @@ bool Any::MergePartialFromCodedStream(
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:google.protobuf.Any)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
@ -352,9 +348,7 @@ size_t Any::ByteSizeLong() const {
|
||||
}
|
||||
|
||||
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = cached_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
SetCachedSize(cached_size);
|
||||
return total_size;
|
||||
}
|
||||
|
||||
@ -414,10 +408,11 @@ void Any::Swap(Any* other) {
|
||||
}
|
||||
void Any::InternalSwap(Any* other) {
|
||||
using std::swap;
|
||||
type_url_.Swap(&other->type_url_);
|
||||
value_.Swap(&other->value_);
|
||||
type_url_.Swap(&other->type_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
value_.Swap(&other->value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata Any::GetMetadata() const {
|
||||
@ -431,7 +426,7 @@ void Any::InternalSwap(Any* other) {
|
||||
} // namespace google
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Any* Arena::Create< ::google::protobuf::Any >(Arena* arena) {
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Any* Arena::CreateMaybeMessage< ::google::protobuf::Any >(Arena* arena) {
|
||||
return Arena::CreateInternal< ::google::protobuf::Any >(arena);
|
||||
}
|
||||
} // namespace protobuf
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: google/protobuf/any.proto
|
||||
|
||||
#ifndef PROTOBUF_google_2fprotobuf_2fany_2eproto_INCLUDED
|
||||
#define PROTOBUF_google_2fprotobuf_2fany_2eproto_INCLUDED
|
||||
#ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
|
||||
#define PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <google/protobuf/arenastring.h>
|
||||
#include <google/protobuf/generated_message_table_driven.h>
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
#include <google/protobuf/inlined_string_field.h>
|
||||
#include <google/protobuf/metadata.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
|
||||
@ -31,6 +32,7 @@
|
||||
#include <google/protobuf/unknown_field_set.h>
|
||||
#include <google/protobuf/any.h>
|
||||
// @@protoc_insertion_point(includes)
|
||||
#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fany_2eproto LIBPROTOBUF_EXPORT
|
||||
|
||||
namespace protobuf_google_2fprotobuf_2fany_2eproto {
|
||||
// Internal implementation detail -- do not use these members.
|
||||
@ -43,11 +45,6 @@ struct LIBPROTOBUF_EXPORT TableStruct {
|
||||
static const ::google::protobuf::uint32 offsets[];
|
||||
};
|
||||
void LIBPROTOBUF_EXPORT AddDescriptors();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsAnyImpl();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsAny();
|
||||
inline void LIBPROTOBUF_EXPORT InitDefaults() {
|
||||
InitDefaultsAny();
|
||||
}
|
||||
} // namespace protobuf_google_2fprotobuf_2fany_2eproto
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -58,7 +55,7 @@ LIBPROTOBUF_EXPORT extern AnyDefaultTypeInternal _Any_default_instance_;
|
||||
} // namespace google
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Any* Arena::Create< ::google::protobuf::Any>(Arena*);
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Any* Arena::CreateMaybeMessage<::google::protobuf::Any>(Arena*);
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
namespace google {
|
||||
@ -100,7 +97,7 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
return reinterpret_cast<const Any*>(
|
||||
&_Any_default_instance_);
|
||||
}
|
||||
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
|
||||
static constexpr int kIndexInFileMessages =
|
||||
0;
|
||||
|
||||
// implements Any -----------------------------------------------
|
||||
@ -112,6 +109,8 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
template<typename T> bool Is() const {
|
||||
return _any_metadata_.Is<T>();
|
||||
}
|
||||
static bool ParseAnyTypeUrl(const string& type_url,
|
||||
string* full_type_name);
|
||||
|
||||
void Swap(Any* other);
|
||||
friend void swap(Any& a, Any& b) {
|
||||
@ -120,32 +119,33 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Any* New() const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Any>(NULL);
|
||||
inline Any* New() const final {
|
||||
return CreateMaybeMessage<Any>(NULL);
|
||||
}
|
||||
|
||||
Any* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Any>(arena);
|
||||
Any* New(::google::protobuf::Arena* arena) const final {
|
||||
return CreateMaybeMessage<Any>(arena);
|
||||
}
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) final;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) final;
|
||||
void CopyFrom(const Any& from);
|
||||
void MergeFrom(const Any& from);
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
void Clear() final;
|
||||
bool IsInitialized() const final;
|
||||
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
size_t ByteSizeLong() const final;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedInputStream* input) final;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedOutputStream* output) const final;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
bool deterministic, ::google::protobuf::uint8* target) const final;
|
||||
int GetCachedSize() const final { return _cached_size_.Get(); }
|
||||
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void SetCachedSize(int size) const final;
|
||||
void InternalSwap(Any* other);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
@ -156,7 +156,7 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
::google::protobuf::Metadata GetMetadata() const final;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
@ -196,10 +196,9 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
|
||||
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
|
||||
::google::protobuf::internal::ArenaStringPtr type_url_;
|
||||
::google::protobuf::internal::ArenaStringPtr value_;
|
||||
mutable int _cached_size_;
|
||||
mutable ::google::protobuf::internal::CachedSize _cached_size_;
|
||||
::google::protobuf::internal::AnyMetadata _any_metadata_;
|
||||
friend struct ::protobuf_google_2fprotobuf_2fany_2eproto::TableStruct;
|
||||
friend void ::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAnyImpl();
|
||||
};
|
||||
// ===================================================================
|
||||
|
||||
@ -329,4 +328,4 @@ inline void Any::set_allocated_value(::std::string* value) {
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
||||
|
||||
#endif // PROTOBUF_google_2fprotobuf_2fany_2eproto_INCLUDED
|
||||
#endif // PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
#include <google/protobuf/stubs/once.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/wire_format_lite_inl.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
@ -19,6 +18,17 @@
|
||||
#include "third_party/protobuf/version.h"
|
||||
#endif
|
||||
// @@protoc_insertion_point(includes)
|
||||
|
||||
namespace protobuf_google_2fprotobuf_2fapi_2eproto {
|
||||
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fapi_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Mixin;
|
||||
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fapi_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Method;
|
||||
} // namespace protobuf_google_2fprotobuf_2fapi_2eproto
|
||||
namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto {
|
||||
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext;
|
||||
} // namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto
|
||||
namespace protobuf_google_2fprotobuf_2ftype_2eproto {
|
||||
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Option;
|
||||
} // namespace protobuf_google_2fprotobuf_2ftype_2eproto
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class ApiDefaultTypeInternal {
|
||||
@ -39,18 +49,9 @@ class MixinDefaultTypeInternal {
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
namespace protobuf_google_2fprotobuf_2fapi_2eproto {
|
||||
void InitDefaultsApiImpl() {
|
||||
static void InitDefaultsApi() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
|
||||
#else
|
||||
::google::protobuf::internal::InitProtobufDefaults();
|
||||
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMethod();
|
||||
protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsOption();
|
||||
protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::InitDefaultsSourceContext();
|
||||
protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMixin();
|
||||
{
|
||||
void* ptr = &::google::protobuf::_Api_default_instance_;
|
||||
new (ptr) ::google::protobuf::Api();
|
||||
@ -59,20 +60,16 @@ void InitDefaultsApiImpl() {
|
||||
::google::protobuf::Api::InitAsDefaultInstance();
|
||||
}
|
||||
|
||||
void InitDefaultsApi() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsApiImpl);
|
||||
}
|
||||
LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<4> scc_info_Api =
|
||||
{{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 4, InitDefaultsApi}, {
|
||||
&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Method.base,
|
||||
&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,
|
||||
&protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::scc_info_SourceContext.base,
|
||||
&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Mixin.base,}};
|
||||
|
||||
void InitDefaultsMethodImpl() {
|
||||
static void InitDefaultsMethod() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
|
||||
#else
|
||||
::google::protobuf::internal::InitProtobufDefaults();
|
||||
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsOption();
|
||||
{
|
||||
void* ptr = &::google::protobuf::_Method_default_instance_;
|
||||
new (ptr) ::google::protobuf::Method();
|
||||
@ -81,19 +78,13 @@ void InitDefaultsMethodImpl() {
|
||||
::google::protobuf::Method::InitAsDefaultInstance();
|
||||
}
|
||||
|
||||
void InitDefaultsMethod() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsMethodImpl);
|
||||
}
|
||||
LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Method =
|
||||
{{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethod}, {
|
||||
&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,}};
|
||||
|
||||
void InitDefaultsMixinImpl() {
|
||||
static void InitDefaultsMixin() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
::google::protobuf::internal::InitProtobufDefaultsForceUnique();
|
||||
#else
|
||||
::google::protobuf::internal::InitProtobufDefaults();
|
||||
#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
|
||||
{
|
||||
void* ptr = &::google::protobuf::_Mixin_default_instance_;
|
||||
new (ptr) ::google::protobuf::Mixin();
|
||||
@ -102,9 +93,13 @@ void InitDefaultsMixinImpl() {
|
||||
::google::protobuf::Mixin::InitAsDefaultInstance();
|
||||
}
|
||||
|
||||
void InitDefaultsMixin() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &InitDefaultsMixinImpl);
|
||||
LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Mixin =
|
||||
{{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsMixin}, {}};
|
||||
|
||||
void InitDefaults() {
|
||||
::google::protobuf::internal::InitSCC(&scc_info_Api.base);
|
||||
::google::protobuf::internal::InitSCC(&scc_info_Method.base);
|
||||
::google::protobuf::internal::InitSCC(&scc_info_Mixin.base);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata file_level_metadata[3];
|
||||
@ -156,15 +151,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = {
|
||||
|
||||
void protobuf_AssignDescriptors() {
|
||||
AddDescriptors();
|
||||
::google::protobuf::MessageFactory* factory = NULL;
|
||||
AssignDescriptors(
|
||||
"google/protobuf/api.proto", schemas, file_default_instances, TableStruct::offsets, factory,
|
||||
"google/protobuf/api.proto", schemas, file_default_instances, TableStruct::offsets,
|
||||
file_level_metadata, NULL, NULL);
|
||||
}
|
||||
|
||||
void protobuf_AssignDescriptorsOnce() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
|
||||
static ::google::protobuf::internal::once_flag once;
|
||||
::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
|
||||
}
|
||||
|
||||
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
|
||||
@ -205,8 +199,8 @@ void AddDescriptorsImpl() {
|
||||
}
|
||||
|
||||
void AddDescriptors() {
|
||||
static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
|
||||
::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
|
||||
static ::google::protobuf::internal::once_flag once;
|
||||
::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
|
||||
}
|
||||
// Force AddDescriptors() to be called at dynamic initialization time.
|
||||
struct StaticDescriptorInitializer {
|
||||
@ -245,9 +239,8 @@ const int Api::kSyntaxFieldNumber;
|
||||
|
||||
Api::Api()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
|
||||
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsApi();
|
||||
}
|
||||
::google::protobuf::internal::InitSCC(
|
||||
&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Api.base);
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:google.protobuf.Api)
|
||||
}
|
||||
@ -256,8 +249,7 @@ Api::Api(const Api& from)
|
||||
_internal_metadata_(NULL),
|
||||
methods_(from.methods_),
|
||||
options_(from.options_),
|
||||
mixins_(from.mixins_),
|
||||
_cached_size_(0) {
|
||||
mixins_(from.mixins_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.name().size() > 0) {
|
||||
@ -282,7 +274,6 @@ void Api::SharedCtor() {
|
||||
::memset(&source_context_, 0, static_cast<size_t>(
|
||||
reinterpret_cast<char*>(&syntax_) -
|
||||
reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
|
||||
_cached_size_ = 0;
|
||||
}
|
||||
|
||||
Api::~Api() {
|
||||
@ -297,9 +288,7 @@ void Api::SharedDtor() {
|
||||
}
|
||||
|
||||
void Api::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
_cached_size_.Set(size);
|
||||
}
|
||||
const ::google::protobuf::Descriptor* Api::descriptor() {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
|
||||
@ -307,7 +296,7 @@ const ::google::protobuf::Descriptor* Api::descriptor() {
|
||||
}
|
||||
|
||||
const Api& Api::default_instance() {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsApi();
|
||||
::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Api.base);
|
||||
return *internal_default_instance();
|
||||
}
|
||||
|
||||
@ -337,7 +326,7 @@ bool Api::MergePartialFromCodedStream(
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:google.protobuf.Api)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
@ -503,7 +492,7 @@ void Api::SerializeWithCachedSizes(
|
||||
// .google.protobuf.SourceContext source_context = 5;
|
||||
if (this->has_source_context()) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
|
||||
5, *source_context_, output);
|
||||
5, this->_internal_source_context(), output);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
@ -577,7 +566,7 @@ void Api::SerializeWithCachedSizes(
|
||||
if (this->has_source_context()) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::
|
||||
InternalWriteMessageToArray(
|
||||
5, *source_context_, deterministic, target);
|
||||
5, this->_internal_source_context(), deterministic, target);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
@ -672,9 +661,7 @@ size_t Api::ByteSizeLong() const {
|
||||
}
|
||||
|
||||
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = cached_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
SetCachedSize(cached_size);
|
||||
return total_size;
|
||||
}
|
||||
|
||||
@ -746,12 +733,13 @@ void Api::InternalSwap(Api* other) {
|
||||
CastToBase(&methods_)->InternalSwap(CastToBase(&other->methods_));
|
||||
CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
|
||||
CastToBase(&mixins_)->InternalSwap(CastToBase(&other->mixins_));
|
||||
name_.Swap(&other->name_);
|
||||
version_.Swap(&other->version_);
|
||||
name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
version_.Swap(&other->version_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
swap(source_context_, other->source_context_);
|
||||
swap(syntax_, other->syntax_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata Api::GetMetadata() const {
|
||||
@ -779,17 +767,15 @@ const int Method::kSyntaxFieldNumber;
|
||||
|
||||
Method::Method()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
|
||||
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMethod();
|
||||
}
|
||||
::google::protobuf::internal::InitSCC(
|
||||
&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Method.base);
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:google.protobuf.Method)
|
||||
}
|
||||
Method::Method(const Method& from)
|
||||
: ::google::protobuf::Message(),
|
||||
_internal_metadata_(NULL),
|
||||
options_(from.options_),
|
||||
_cached_size_(0) {
|
||||
options_(from.options_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.name().size() > 0) {
|
||||
@ -816,7 +802,6 @@ void Method::SharedCtor() {
|
||||
::memset(&request_streaming_, 0, static_cast<size_t>(
|
||||
reinterpret_cast<char*>(&syntax_) -
|
||||
reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
|
||||
_cached_size_ = 0;
|
||||
}
|
||||
|
||||
Method::~Method() {
|
||||
@ -831,9 +816,7 @@ void Method::SharedDtor() {
|
||||
}
|
||||
|
||||
void Method::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
_cached_size_.Set(size);
|
||||
}
|
||||
const ::google::protobuf::Descriptor* Method::descriptor() {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
|
||||
@ -841,7 +824,7 @@ const ::google::protobuf::Descriptor* Method::descriptor() {
|
||||
}
|
||||
|
||||
const Method& Method::default_instance() {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMethod();
|
||||
::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Method.base);
|
||||
return *internal_default_instance();
|
||||
}
|
||||
|
||||
@ -868,7 +851,7 @@ bool Method::MergePartialFromCodedStream(
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:google.protobuf.Method)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
@ -1193,9 +1176,7 @@ size_t Method::ByteSizeLong() const {
|
||||
}
|
||||
|
||||
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = cached_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
SetCachedSize(cached_size);
|
||||
return total_size;
|
||||
}
|
||||
|
||||
@ -1270,14 +1251,16 @@ void Method::Swap(Method* other) {
|
||||
void Method::InternalSwap(Method* other) {
|
||||
using std::swap;
|
||||
CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
|
||||
name_.Swap(&other->name_);
|
||||
request_type_url_.Swap(&other->request_type_url_);
|
||||
response_type_url_.Swap(&other->response_type_url_);
|
||||
name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
request_type_url_.Swap(&other->request_type_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
response_type_url_.Swap(&other->response_type_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
swap(request_streaming_, other->request_streaming_);
|
||||
swap(response_streaming_, other->response_streaming_);
|
||||
swap(syntax_, other->syntax_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata Method::GetMetadata() const {
|
||||
@ -1297,16 +1280,14 @@ const int Mixin::kRootFieldNumber;
|
||||
|
||||
Mixin::Mixin()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
|
||||
if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMixin();
|
||||
}
|
||||
::google::protobuf::internal::InitSCC(
|
||||
&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Mixin.base);
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:google.protobuf.Mixin)
|
||||
}
|
||||
Mixin::Mixin(const Mixin& from)
|
||||
: ::google::protobuf::Message(),
|
||||
_internal_metadata_(NULL),
|
||||
_cached_size_(0) {
|
||||
_internal_metadata_(NULL) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.name().size() > 0) {
|
||||
@ -1322,7 +1303,6 @@ Mixin::Mixin(const Mixin& from)
|
||||
void Mixin::SharedCtor() {
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
root_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
_cached_size_ = 0;
|
||||
}
|
||||
|
||||
Mixin::~Mixin() {
|
||||
@ -1336,9 +1316,7 @@ void Mixin::SharedDtor() {
|
||||
}
|
||||
|
||||
void Mixin::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
_cached_size_.Set(size);
|
||||
}
|
||||
const ::google::protobuf::Descriptor* Mixin::descriptor() {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
|
||||
@ -1346,7 +1324,7 @@ const ::google::protobuf::Descriptor* Mixin::descriptor() {
|
||||
}
|
||||
|
||||
const Mixin& Mixin::default_instance() {
|
||||
::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMixin();
|
||||
::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Mixin.base);
|
||||
return *internal_default_instance();
|
||||
}
|
||||
|
||||
@ -1368,7 +1346,7 @@ bool Mixin::MergePartialFromCodedStream(
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:google.protobuf.Mixin)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
@ -1518,9 +1496,7 @@ size_t Mixin::ByteSizeLong() const {
|
||||
}
|
||||
|
||||
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = cached_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
SetCachedSize(cached_size);
|
||||
return total_size;
|
||||
}
|
||||
|
||||
@ -1580,10 +1556,11 @@ void Mixin::Swap(Mixin* other) {
|
||||
}
|
||||
void Mixin::InternalSwap(Mixin* other) {
|
||||
using std::swap;
|
||||
name_.Swap(&other->name_);
|
||||
root_.Swap(&other->root_);
|
||||
name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
root_.Swap(&other->root_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
GetArenaNoVirtual());
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata Mixin::GetMetadata() const {
|
||||
@ -1597,13 +1574,13 @@ void Mixin::InternalSwap(Mixin* other) {
|
||||
} // namespace google
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Api* Arena::Create< ::google::protobuf::Api >(Arena* arena) {
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Api* Arena::CreateMaybeMessage< ::google::protobuf::Api >(Arena* arena) {
|
||||
return Arena::CreateInternal< ::google::protobuf::Api >(arena);
|
||||
}
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Method* Arena::Create< ::google::protobuf::Method >(Arena* arena) {
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Method* Arena::CreateMaybeMessage< ::google::protobuf::Method >(Arena* arena) {
|
||||
return Arena::CreateInternal< ::google::protobuf::Method >(arena);
|
||||
}
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Mixin* Arena::Create< ::google::protobuf::Mixin >(Arena* arena) {
|
||||
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::Mixin* Arena::CreateMaybeMessage< ::google::protobuf::Mixin >(Arena* arena) {
|
||||
return Arena::CreateInternal< ::google::protobuf::Mixin >(arena);
|
||||
}
|
||||
} // namespace protobuf
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: google/protobuf/api.proto
|
||||
|
||||
#ifndef PROTOBUF_google_2fprotobuf_2fapi_2eproto_INCLUDED
|
||||
#define PROTOBUF_google_2fprotobuf_2fapi_2eproto_INCLUDED
|
||||
#ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
|
||||
#define PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <google/protobuf/arenastring.h>
|
||||
#include <google/protobuf/generated_message_table_driven.h>
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
#include <google/protobuf/inlined_string_field.h>
|
||||
#include <google/protobuf/metadata.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
|
||||
@ -32,6 +33,7 @@
|
||||
#include <google/protobuf/source_context.pb.h>
|
||||
#include <google/protobuf/type.pb.h>
|
||||
// @@protoc_insertion_point(includes)
|
||||
#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fapi_2eproto LIBPROTOBUF_EXPORT
|
||||
|
||||
namespace protobuf_google_2fprotobuf_2fapi_2eproto {
|
||||
// Internal implementation detail -- do not use these members.
|
||||
@ -44,17 +46,6 @@ struct LIBPROTOBUF_EXPORT TableStruct {
|
||||
static const ::google::protobuf::uint32 offsets[];
|
||||
};
|
||||
void LIBPROTOBUF_EXPORT AddDescriptors();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsApiImpl();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsApi();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsMethodImpl();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsMethod();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsMixinImpl();
|
||||
void LIBPROTOBUF_EXPORT InitDefaultsMixin();
|
||||
inline void LIBPROTOBUF_EXPORT InitDefaults() {
|
||||
InitDefaultsApi();
|
||||
InitDefaultsMethod();
|
||||
InitDefaultsMixin();
|
||||
}
|
||||
} // namespace protobuf_google_2fprotobuf_2fapi_2eproto
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -71,9 +62,9 @@ LIBPROTOBUF_EXPORT extern MixinDefaultTypeInternal _Mixin_default_instance_;
|
||||
} // namespace google
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Api* Arena::Create< ::google::protobuf::Api>(Arena*);
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Method* Arena::Create< ::google::protobuf::Method>(Arena*);
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Mixin* Arena::Create< ::google::protobuf::Mixin>(Arena*);
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Api* Arena::CreateMaybeMessage<::google::protobuf::Api>(Arena*);
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Method* Arena::CreateMaybeMessage<::google::protobuf::Method>(Arena*);
|
||||
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Mixin* Arena::CreateMaybeMessage<::google::protobuf::Mixin>(Arena*);
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
namespace google {
|
||||
@ -115,7 +106,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
return reinterpret_cast<const Api*>(
|
||||
&_Api_default_instance_);
|
||||
}
|
||||
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
|
||||
static constexpr int kIndexInFileMessages =
|
||||
0;
|
||||
|
||||
void Swap(Api* other);
|
||||
@ -125,32 +116,33 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Api* New() const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Api>(NULL);
|
||||
inline Api* New() const final {
|
||||
return CreateMaybeMessage<Api>(NULL);
|
||||
}
|
||||
|
||||
Api* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Api>(arena);
|
||||
Api* New(::google::protobuf::Arena* arena) const final {
|
||||
return CreateMaybeMessage<Api>(arena);
|
||||
}
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) final;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) final;
|
||||
void CopyFrom(const Api& from);
|
||||
void MergeFrom(const Api& from);
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
void Clear() final;
|
||||
bool IsInitialized() const final;
|
||||
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
size_t ByteSizeLong() const final;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedInputStream* input) final;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedOutputStream* output) const final;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
bool deterministic, ::google::protobuf::uint8* target) const final;
|
||||
int GetCachedSize() const final { return _cached_size_.Get(); }
|
||||
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void SetCachedSize(int size) const final;
|
||||
void InternalSwap(Api* other);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
@ -161,7 +153,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
::google::protobuf::Metadata GetMetadata() const final;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
@ -235,6 +227,9 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
bool has_source_context() const;
|
||||
void clear_source_context();
|
||||
static const int kSourceContextFieldNumber = 5;
|
||||
private:
|
||||
const ::google::protobuf::SourceContext& _internal_source_context() const;
|
||||
public:
|
||||
const ::google::protobuf::SourceContext& source_context() const;
|
||||
::google::protobuf::SourceContext* release_source_context();
|
||||
::google::protobuf::SourceContext* mutable_source_context();
|
||||
@ -257,9 +252,8 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
|
||||
::google::protobuf::internal::ArenaStringPtr version_;
|
||||
::google::protobuf::SourceContext* source_context_;
|
||||
int syntax_;
|
||||
mutable int _cached_size_;
|
||||
mutable ::google::protobuf::internal::CachedSize _cached_size_;
|
||||
friend struct ::protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
|
||||
friend void ::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsApiImpl();
|
||||
};
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@ -297,7 +291,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
return reinterpret_cast<const Method*>(
|
||||
&_Method_default_instance_);
|
||||
}
|
||||
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
|
||||
static constexpr int kIndexInFileMessages =
|
||||
1;
|
||||
|
||||
void Swap(Method* other);
|
||||
@ -307,32 +301,33 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Method* New() const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Method>(NULL);
|
||||
inline Method* New() const final {
|
||||
return CreateMaybeMessage<Method>(NULL);
|
||||
}
|
||||
|
||||
Method* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Method>(arena);
|
||||
Method* New(::google::protobuf::Arena* arena) const final {
|
||||
return CreateMaybeMessage<Method>(arena);
|
||||
}
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) final;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) final;
|
||||
void CopyFrom(const Method& from);
|
||||
void MergeFrom(const Method& from);
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
void Clear() final;
|
||||
bool IsInitialized() const final;
|
||||
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
size_t ByteSizeLong() const final;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedInputStream* input) final;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedOutputStream* output) const final;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
bool deterministic, ::google::protobuf::uint8* target) const final;
|
||||
int GetCachedSize() const final { return _cached_size_.Get(); }
|
||||
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void SetCachedSize(int size) const final;
|
||||
void InternalSwap(Method* other);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
@ -343,7 +338,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
::google::protobuf::Metadata GetMetadata() const final;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
@ -432,9 +427,8 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
|
||||
bool request_streaming_;
|
||||
bool response_streaming_;
|
||||
int syntax_;
|
||||
mutable int _cached_size_;
|
||||
mutable ::google::protobuf::internal::CachedSize _cached_size_;
|
||||
friend struct ::protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
|
||||
friend void ::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMethodImpl();
|
||||
};
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@ -472,7 +466,7 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
return reinterpret_cast<const Mixin*>(
|
||||
&_Mixin_default_instance_);
|
||||
}
|
||||
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
|
||||
static constexpr int kIndexInFileMessages =
|
||||
2;
|
||||
|
||||
void Swap(Mixin* other);
|
||||
@ -482,32 +476,33 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Mixin* New() const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Mixin>(NULL);
|
||||
inline Mixin* New() const final {
|
||||
return CreateMaybeMessage<Mixin>(NULL);
|
||||
}
|
||||
|
||||
Mixin* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL {
|
||||
return ::google::protobuf::Arena::Create<Mixin>(arena);
|
||||
Mixin* New(::google::protobuf::Arena* arena) const final {
|
||||
return CreateMaybeMessage<Mixin>(arena);
|
||||
}
|
||||
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
|
||||
void CopyFrom(const ::google::protobuf::Message& from) final;
|
||||
void MergeFrom(const ::google::protobuf::Message& from) final;
|
||||
void CopyFrom(const Mixin& from);
|
||||
void MergeFrom(const Mixin& from);
|
||||
void Clear() PROTOBUF_FINAL;
|
||||
bool IsInitialized() const PROTOBUF_FINAL;
|
||||
void Clear() final;
|
||||
bool IsInitialized() const final;
|
||||
|
||||
size_t ByteSizeLong() const PROTOBUF_FINAL;
|
||||
size_t ByteSizeLong() const final;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedInputStream* input) final;
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
|
||||
::google::protobuf::io::CodedOutputStream* output) const final;
|
||||
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
|
||||
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
|
||||
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
|
||||
bool deterministic, ::google::protobuf::uint8* target) const final;
|
||||
int GetCachedSize() const final { return _cached_size_.Get(); }
|
||||
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const PROTOBUF_FINAL;
|
||||
void SetCachedSize(int size) const final;
|
||||
void InternalSwap(Mixin* other);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
@ -518,7 +513,7 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
|
||||
::google::protobuf::Metadata GetMetadata() const final;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
@ -558,9 +553,8 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
|
||||
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
|
||||
::google::protobuf::internal::ArenaStringPtr name_;
|
||||
::google::protobuf::internal::ArenaStringPtr root_;
|
||||
mutable int _cached_size_;
|
||||
mutable ::google::protobuf::internal::CachedSize _cached_size_;
|
||||
friend struct ::protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
|
||||
friend void ::protobuf_google_2fprotobuf_2fapi_2eproto::InitDefaultsMixinImpl();
|
||||
};
|
||||
// ===================================================================
|
||||
|
||||
@ -740,6 +734,9 @@ inline void Api::set_allocated_version(::std::string* version) {
|
||||
inline bool Api::has_source_context() const {
|
||||
return this != internal_default_instance() && source_context_ != NULL;
|
||||
}
|
||||
inline const ::google::protobuf::SourceContext& Api::_internal_source_context() const {
|
||||
return *source_context_;
|
||||
}
|
||||
inline const ::google::protobuf::SourceContext& Api::source_context() const {
|
||||
const ::google::protobuf::SourceContext* p = source_context_;
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
|
||||
@ -756,8 +753,8 @@ inline ::google::protobuf::SourceContext* Api::release_source_context() {
|
||||
inline ::google::protobuf::SourceContext* Api::mutable_source_context() {
|
||||
|
||||
if (source_context_ == NULL) {
|
||||
source_context_ = ::google::protobuf::Arena::Create< ::google::protobuf::SourceContext >(
|
||||
GetArenaNoVirtual());
|
||||
auto* p = CreateMaybeMessage<::google::protobuf::SourceContext>(GetArenaNoVirtual());
|
||||
source_context_ = p;
|
||||
}
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context)
|
||||
return source_context_;
|
||||
@ -1182,4 +1179,4 @@ inline void Mixin::set_allocated_root(::std::string* root) {
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
||||
|
||||
#endif // PROTOBUF_google_2fprotobuf_2fapi_2eproto_INCLUDED
|
||||
#endif // PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
|
||||
|
@ -48,7 +48,7 @@ namespace protobuf {
|
||||
namespace internal {
|
||||
|
||||
|
||||
google::protobuf::internal::SequenceNumber ArenaImpl::lifecycle_id_generator_;
|
||||
std::atomic<int64> ArenaImpl::lifecycle_id_generator_;
|
||||
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
|
||||
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
|
||||
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
|
||||
@ -65,9 +65,10 @@ GOOGLE_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL}
|
||||
#endif
|
||||
|
||||
void ArenaImpl::Init() {
|
||||
lifecycle_id_ = lifecycle_id_generator_.GetNext();
|
||||
google::protobuf::internal::NoBarrier_Store(&hint_, 0);
|
||||
google::protobuf::internal::NoBarrier_Store(&threads_, 0);
|
||||
lifecycle_id_ =
|
||||
lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed);
|
||||
hint_.store(nullptr, std::memory_order_relaxed);
|
||||
threads_.store(nullptr, std::memory_order_relaxed);
|
||||
|
||||
if (initial_block_) {
|
||||
// Thread which calls Init() owns the first block. This allows the
|
||||
@ -77,13 +78,12 @@ void ArenaImpl::Init() {
|
||||
SerialArena* serial =
|
||||
SerialArena::New(initial_block_, &thread_cache(), this);
|
||||
serial->set_next(NULL);
|
||||
google::protobuf::internal::NoBarrier_Store(&threads_,
|
||||
reinterpret_cast<google::protobuf::internal::AtomicWord>(serial));
|
||||
google::protobuf::internal::NoBarrier_Store(&space_allocated_,
|
||||
options_.initial_block_size);
|
||||
threads_.store(serial, std::memory_order_relaxed);
|
||||
space_allocated_.store(options_.initial_block_size,
|
||||
std::memory_order_relaxed);
|
||||
CacheSerialArena(serial);
|
||||
} else {
|
||||
google::protobuf::internal::NoBarrier_Store(&space_allocated_, 0);
|
||||
space_allocated_.store(0, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) {
|
||||
|
||||
void* mem = options_.block_alloc(size);
|
||||
Block* b = new (mem) Block(size, last_block);
|
||||
google::protobuf::internal::NoBarrier_AtomicIncrement(&space_allocated_, size);
|
||||
space_allocated_.fetch_add(size, std::memory_order_relaxed);
|
||||
return b;
|
||||
}
|
||||
|
||||
@ -142,6 +142,7 @@ void ArenaImpl::SerialArena::AddCleanupFallback(void* elem,
|
||||
AddCleanup(elem, cleanup);
|
||||
}
|
||||
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_FUNC_ALIGN(32)
|
||||
void* ArenaImpl::AllocateAligned(size_t n) {
|
||||
SerialArena* arena;
|
||||
if (GOOGLE_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
|
||||
@ -199,8 +200,7 @@ bool ArenaImpl::GetSerialArenaFast(ArenaImpl::SerialArena** arena) {
|
||||
|
||||
// Check whether we own the last accessed SerialArena on this arena. This
|
||||
// fast path optimizes the case where a single thread uses multiple arenas.
|
||||
SerialArena* serial =
|
||||
reinterpret_cast<SerialArena*>(google::protobuf::internal::Acquire_Load(&hint_));
|
||||
SerialArena* serial = hint_.load(std::memory_order_acquire);
|
||||
if (GOOGLE_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) {
|
||||
*arena = serial;
|
||||
return true;
|
||||
@ -235,12 +235,11 @@ void* ArenaImpl::SerialArena::AllocateAlignedFallback(size_t n) {
|
||||
}
|
||||
|
||||
uint64 ArenaImpl::SpaceAllocated() const {
|
||||
return google::protobuf::internal::NoBarrier_Load(&space_allocated_);
|
||||
return space_allocated_.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
uint64 ArenaImpl::SpaceUsed() const {
|
||||
SerialArena* serial =
|
||||
reinterpret_cast<SerialArena*>(google::protobuf::internal::Acquire_Load(&threads_));
|
||||
SerialArena* serial = threads_.load(std::memory_order_acquire);
|
||||
uint64 space_used = 0;
|
||||
for ( ; serial; serial = serial->next()) {
|
||||
space_used += serial->SpaceUsed();
|
||||
@ -264,8 +263,7 @@ uint64 ArenaImpl::FreeBlocks() {
|
||||
uint64 space_allocated = 0;
|
||||
// By omitting an Acquire barrier we ensure that any user code that doesn't
|
||||
// properly synchronize Reset() or the destructor will throw a TSAN warning.
|
||||
SerialArena* serial =
|
||||
reinterpret_cast<SerialArena*>(google::protobuf::internal::NoBarrier_Load(&threads_));
|
||||
SerialArena* serial = threads_.load(std::memory_order_relaxed);
|
||||
|
||||
while (serial) {
|
||||
// This is inside a block we are freeing, so we need to read it now.
|
||||
@ -311,8 +309,7 @@ uint64 ArenaImpl::SerialArena::Free(ArenaImpl::SerialArena* serial,
|
||||
void ArenaImpl::CleanupList() {
|
||||
// By omitting an Acquire barrier we ensure that any user code that doesn't
|
||||
// properly synchronize Reset() or the destructor will throw a TSAN warning.
|
||||
SerialArena* serial =
|
||||
reinterpret_cast<SerialArena*>(google::protobuf::internal::NoBarrier_Load(&threads_));
|
||||
SerialArena* serial = threads_.load(std::memory_order_relaxed);
|
||||
|
||||
for ( ; serial; serial = serial->next()) {
|
||||
serial->CleanupList();
|
||||
@ -368,8 +365,7 @@ ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner,
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
|
||||
ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) {
|
||||
// Look for this SerialArena in our linked list.
|
||||
SerialArena* serial =
|
||||
reinterpret_cast<SerialArena*>(google::protobuf::internal::Acquire_Load(&threads_));
|
||||
SerialArena* serial = threads_.load(std::memory_order_acquire);
|
||||
for ( ; serial; serial = serial->next()) {
|
||||
if (serial->owner() == me) {
|
||||
break;
|
||||
@ -382,12 +378,11 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) {
|
||||
Block* b = NewBlock(NULL, kSerialArenaSize);
|
||||
serial = SerialArena::New(b, me, this);
|
||||
|
||||
google::protobuf::internal::AtomicWord head;
|
||||
SerialArena* head = threads_.load(std::memory_order_relaxed);
|
||||
do {
|
||||
head = google::protobuf::internal::NoBarrier_Load(&threads_);
|
||||
serial->set_next(reinterpret_cast<SerialArena*>(head));
|
||||
} while (google::protobuf::internal::Release_CompareAndSwap(
|
||||
&threads_, head, reinterpret_cast<google::protobuf::internal::AtomicWord>(serial)) != head);
|
||||
serial->set_next(head);
|
||||
} while (!threads_.compare_exchange_weak(
|
||||
head, serial, std::memory_order_release, std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
CacheSerialArena(serial);
|
||||
|
@ -37,9 +37,6 @@
|
||||
#ifdef max
|
||||
#undef max // Visual Studio defines this macro
|
||||
#endif
|
||||
#if LANG_CXX11
|
||||
#include <google/protobuf/stubs/type_traits.h>
|
||||
#endif
|
||||
#if defined(_MSC_VER) && !_HAS_EXCEPTIONS
|
||||
// Work around bugs in MSVC <typeinfo> header when _HAS_EXCEPTIONS=0.
|
||||
#include <exception>
|
||||
@ -53,10 +50,13 @@ using type_info = ::type_info;
|
||||
|
||||
#include <google/protobuf/arena_impl.h>
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
struct ArenaOptions;
|
||||
|
||||
struct ArenaOptions; // defined below
|
||||
|
||||
} // namespace protobuf
|
||||
|
||||
namespace quality_webanswers {
|
||||
@ -66,27 +66,32 @@ void TempPrivateWorkAround(::google::protobuf::ArenaOptions* arena_options);
|
||||
} // namespace quality_webanswers
|
||||
|
||||
namespace protobuf {
|
||||
|
||||
class Arena; // defined below
|
||||
class Message; // defined in message.h
|
||||
class MessageLite;
|
||||
|
||||
namespace arena_metrics {
|
||||
|
||||
void EnableArenaMetrics(::google::protobuf::ArenaOptions* options);
|
||||
|
||||
} // namespace arena_metrics
|
||||
|
||||
class Arena; // defined below
|
||||
class Message; // message.h
|
||||
|
||||
namespace internal {
|
||||
struct ArenaStringPtr; // arenastring.h
|
||||
class LazyField; // lazy_field.h
|
||||
|
||||
template<typename Type>
|
||||
class GenericTypeHandler; // repeated_field.h
|
||||
struct ArenaStringPtr; // defined in arenastring.h
|
||||
class LazyField; // defined in lazy_field.h
|
||||
|
||||
template <typename Type>
|
||||
class GenericTypeHandler; // defined in repeated_field.h
|
||||
|
||||
// Templated cleanup methods.
|
||||
template<typename T> void arena_destruct_object(void* object) {
|
||||
template <typename T>
|
||||
void arena_destruct_object(void* object) {
|
||||
reinterpret_cast<T*>(object)->~T();
|
||||
}
|
||||
template<typename T> void arena_delete_object(void* object) {
|
||||
template <typename T>
|
||||
void arena_delete_object(void* object) {
|
||||
delete reinterpret_cast<T*>(object);
|
||||
}
|
||||
inline void arena_free(void* object, size_t size) {
|
||||
@ -165,12 +170,12 @@ struct ArenaOptions {
|
||||
// intentionally want to avoid monitoring an allocation. (i.e. internal
|
||||
// allocations for managing the arena)
|
||||
void (*on_arena_allocation)(const std::type_info* allocated_type,
|
||||
uint64 alloc_size, void* cookie);
|
||||
uint64 alloc_size, void* cookie);
|
||||
|
||||
// Constants define default starting block size and max block size for
|
||||
// arena allocator behavior -- see descriptions above.
|
||||
static const size_t kDefaultStartBlockSize = 256;
|
||||
static const size_t kDefaultMaxBlockSize = 8192;
|
||||
static const size_t kDefaultMaxBlockSize = 8192;
|
||||
|
||||
friend void ::google::protobuf::arena_metrics::EnableArenaMetrics(ArenaOptions*);
|
||||
friend void quality_webanswers::TempPrivateWorkAround(ArenaOptions*);
|
||||
@ -285,70 +290,16 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
//
|
||||
// This function also accepts any type T that satisfies the arena message
|
||||
// allocation protocol, documented above.
|
||||
#if LANG_CXX11
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessage(
|
||||
::google::protobuf::Arena* arena, Args&&... args) {
|
||||
Arena* arena, Args&&... args) {
|
||||
static_assert(
|
||||
InternalHelper<T>::is_arena_constructable::value,
|
||||
"CreateMessage can only construct types that are ArenaConstructable");
|
||||
if (arena == NULL) {
|
||||
return new T(NULL, std::forward<Args>(args)...);
|
||||
} else {
|
||||
return arena->CreateMessageInternal<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateMessage(::google::protobuf::Arena* arena) {
|
||||
#if LANG_CXX11
|
||||
static_assert(
|
||||
InternalHelper<T>::is_arena_constructable::value,
|
||||
"CreateMessage can only construct types that are ArenaConstructable");
|
||||
#endif
|
||||
if (arena == NULL) {
|
||||
return new T;
|
||||
} else {
|
||||
return arena->CreateMessageInternal<T>();
|
||||
}
|
||||
}
|
||||
|
||||
// One-argument form of CreateMessage. This is useful for constructing objects
|
||||
// that implement the arena message construction protocol described above but
|
||||
// take additional constructor arguments.
|
||||
template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateMessage(::google::protobuf::Arena* arena, const Arg& arg) {
|
||||
#if LANG_CXX11
|
||||
static_assert(
|
||||
InternalHelper<T>::is_arena_constructable::value,
|
||||
"CreateMessage can only construct types that are ArenaConstructable");
|
||||
#endif
|
||||
if (arena == NULL) {
|
||||
return new T(NULL, arg);
|
||||
} else {
|
||||
return arena->CreateMessageInternal<T>(arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Two-argument form of CreateMessage. This is useful for constructing objects
|
||||
// that implement the arena message construction protocol described above but
|
||||
// take additional constructor arguments.
|
||||
template <typename T, typename Arg1, typename Arg2>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateMessage(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2) {
|
||||
#if LANG_CXX11
|
||||
static_assert(
|
||||
InternalHelper<T>::is_arena_constructable::value,
|
||||
"CreateMessage can only construct types that are ArenaConstructable");
|
||||
#endif
|
||||
if (arena == NULL) {
|
||||
return new T(NULL, arg1, arg2);
|
||||
} else {
|
||||
return arena->CreateMessageInternal<T>(arg1, arg2);
|
||||
}
|
||||
// We must delegate to CreateMaybeMessage() and NOT CreateMessageInternal()
|
||||
// because protobuf generated classes specialize CreateMaybeMessage() and we
|
||||
// need to use that specialization for code size reasons.
|
||||
return Arena::CreateMaybeMessage<T>(arena, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// API to create any objects on the arena. Note that only the object will
|
||||
@ -366,153 +317,11 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// (unless the destructor is trivial). Hence, from T's point of view, it is as
|
||||
// if the object were allocated on the heap (except that the underlying memory
|
||||
// is obtained from the arena).
|
||||
#if LANG_CXX11
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena, Args&&... args) {
|
||||
if (arena == NULL) {
|
||||
return new T(std::forward<Args>(args)...);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena) {
|
||||
if (arena == NULL) {
|
||||
return new T();
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with one constructor argument for the created object.
|
||||
template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena, const Arg& arg) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with two constructor arguments for the created object.
|
||||
template <typename T, typename Arg1, typename Arg2>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena, const Arg1& arg1, const Arg2& arg2) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with three constructor arguments for the created
|
||||
// object.
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2, arg3);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2, arg3);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with four constructor arguments for the created
|
||||
// object.
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2, arg3, arg4);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2, arg3, arg4);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with five constructor arguments for the created
|
||||
// object.
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4,
|
||||
const Arg5& arg5) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2, arg3, arg4, arg5);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with six constructor arguments for the created
|
||||
// object.
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5, typename Arg6>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4,
|
||||
const Arg5& arg5, const Arg6& arg6) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with seven constructor arguments for the created
|
||||
// object.
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5, typename Arg6, typename Arg7>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4,
|
||||
const Arg5& arg5, const Arg6& arg6,
|
||||
const Arg7& arg7) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the above with eight constructor arguments for the created
|
||||
// object.
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5, typename Arg6, typename Arg7,
|
||||
typename Arg8>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* Create(::google::protobuf::Arena* arena,
|
||||
const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4,
|
||||
const Arg5& arg5, const Arg6& arg6,
|
||||
const Arg7& arg7, const Arg8& arg8) {
|
||||
if (arena == NULL) {
|
||||
return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
} else {
|
||||
return arena->CreateInternal<T>(
|
||||
google::protobuf::internal::has_trivial_destructor<T>::value,
|
||||
arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* Create(Arena* arena,
|
||||
Args&&... args) {
|
||||
return CreateNoMessage<T>(arena, is_arena_constructable<T>(),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Create an array of object type T on the arena *without* invoking the
|
||||
@ -521,10 +330,14 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// To ensure safe uses, this function checks at compile time
|
||||
// (when compiled as C++11) that T is trivially default-constructible and
|
||||
// trivially destructible.
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateArray(::google::protobuf::Arena* arena, size_t num_elements) {
|
||||
GOOGLE_CHECK_LE(num_elements,
|
||||
std::numeric_limits<size_t>::max() / sizeof(T))
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateArray(
|
||||
Arena* arena, size_t num_elements) {
|
||||
static_assert(std::is_trivially_default_constructible<T>::value,
|
||||
"CreateArray requires a trivially constructible type");
|
||||
static_assert(std::is_trivially_destructible<T>::value,
|
||||
"CreateArray requires a trivially destructible type");
|
||||
GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T))
|
||||
<< "Requested size is too large to fit into size_t.";
|
||||
if (arena == NULL) {
|
||||
return static_cast<T*>(::operator new[](num_elements * sizeof(T)));
|
||||
@ -566,9 +379,9 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
|
||||
// Adds |object| to a list of heap-allocated objects to be freed with |delete|
|
||||
// when the arena is destroyed or reset.
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
|
||||
void Own(T* object) {
|
||||
OwnInternal(object, google::protobuf::internal::is_convertible<T*, ::google::protobuf::Message*>());
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void Own(T* object) {
|
||||
OwnInternal(object, std::is_convertible<T*, Message*>());
|
||||
}
|
||||
|
||||
// Adds |object| to a list of objects whose destructors will be manually
|
||||
@ -576,8 +389,8 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// that it does not free the underlying memory with |delete|; hence, it is
|
||||
// normally only used for objects that are placement-newed into
|
||||
// arena-allocated memory.
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
|
||||
void OwnDestructor(T* object) {
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void OwnDestructor(T* object) {
|
||||
if (object != NULL) {
|
||||
impl_.AddCleanup(object, &internal::arena_destruct_object<T>);
|
||||
}
|
||||
@ -596,8 +409,9 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// message, or NULL otherwise. This differs from value->GetArena() in that the
|
||||
// latter is a virtual call, while this method is a templated call that
|
||||
// resolves at compile-time.
|
||||
template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static ::google::protobuf::Arena* GetArena(const T* value) {
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static Arena* GetArena(
|
||||
const T* value) {
|
||||
return GetArenaInternal(value, is_arena_constructable<T>());
|
||||
}
|
||||
|
||||
@ -608,80 +422,89 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
template <typename U>
|
||||
static double DestructorSkippable(...);
|
||||
|
||||
typedef google::protobuf::internal::integral_constant<
|
||||
typedef std::integral_constant<
|
||||
bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) ==
|
||||
sizeof(char) ||
|
||||
google::protobuf::internal::has_trivial_destructor<T>::value>
|
||||
std::is_trivially_destructible<T>::value>
|
||||
is_destructor_skippable;
|
||||
|
||||
template<typename U>
|
||||
template <typename U>
|
||||
static char ArenaConstructable(
|
||||
const typename U::InternalArenaConstructable_*);
|
||||
template<typename U>
|
||||
template <typename U>
|
||||
static double ArenaConstructable(...);
|
||||
|
||||
typedef google::protobuf::internal::integral_constant<bool, sizeof(ArenaConstructable<T>(
|
||||
static_cast<const T*>(0))) ==
|
||||
sizeof(char)>
|
||||
typedef std::integral_constant<bool, sizeof(ArenaConstructable<T>(
|
||||
static_cast<const T*>(0))) ==
|
||||
sizeof(char)>
|
||||
is_arena_constructable;
|
||||
|
||||
#if LANG_CXX11
|
||||
template <typename... Args>
|
||||
static T* Construct(void* ptr, Args&&... args) {
|
||||
return new (ptr) T(std::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
template <typename Arg1>
|
||||
static T* Construct(void* ptr, const Arg1& arg1) {
|
||||
return new (ptr) T(arg1);
|
||||
}
|
||||
template <typename Arg1, typename Arg2>
|
||||
static T* Construct(void* ptr, const Arg1& arg1, const Arg2& arg2) {
|
||||
return new (ptr) T(arg1, arg2);
|
||||
}
|
||||
template <typename Arg1, typename Arg2, typename Arg3>
|
||||
static T* Construct(void* ptr, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3) {
|
||||
return new (ptr) T(arg1, arg2, arg3);
|
||||
}
|
||||
#endif // LANG_CXX11
|
||||
|
||||
static Arena* GetArena(const T* p) { return p->GetArenaNoVirtual(); }
|
||||
|
||||
friend class Arena;
|
||||
};
|
||||
|
||||
// Helper typetrait that indicates support for arenas in a type T at compile
|
||||
// Helper typetraits that indicates support for arenas in a type T at compile
|
||||
// time. This is public only to allow construction of higher-level templated
|
||||
// utilities. is_arena_constructable<T>::value is true if the message type T
|
||||
// has arena support enabled, and false otherwise.
|
||||
// utilities.
|
||||
//
|
||||
// is_arena_constructable<T>::value is true if the message type T has arena
|
||||
// support enabled, and false otherwise.
|
||||
//
|
||||
// is_destructor_skippable<T>::value is true if the message type T has told
|
||||
// the arena that it is safe to skip the destructor, and false otherwise.
|
||||
//
|
||||
// This is inside Arena because only Arena has the friend relationships
|
||||
// necessary to see the underlying generated code traits.
|
||||
template <typename T>
|
||||
struct is_arena_constructable : InternalHelper<T>::is_arena_constructable {};
|
||||
template <typename T>
|
||||
struct is_destructor_skippable : InternalHelper<T>::is_destructor_skippable {
|
||||
};
|
||||
|
||||
private:
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateMessageInternal(::google::protobuf::Arena* arena) {
|
||||
#if LANG_CXX11
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessageInternal(
|
||||
Arena* arena, Args&&... args) {
|
||||
static_assert(
|
||||
InternalHelper<T>::is_arena_constructable::value,
|
||||
"CreateMessage can only construct types that are ArenaConstructable");
|
||||
#endif
|
||||
if (arena == NULL) {
|
||||
return new T;
|
||||
return new T(nullptr, std::forward<Args>(args)...);
|
||||
} else {
|
||||
return arena->CreateMessageInternal<T>();
|
||||
return arena->DoCreateMessage<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateInternal(::google::protobuf::Arena* arena) {
|
||||
// This specialization for no arguments is necessary, because its behavior is
|
||||
// slightly different. When the arena pointer is nullptr, it calls T()
|
||||
// instead of T(nullptr).
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessageInternal(
|
||||
Arena* arena) {
|
||||
static_assert(
|
||||
InternalHelper<T>::is_arena_constructable::value,
|
||||
"CreateMessage can only construct types that are ArenaConstructable");
|
||||
if (arena == NULL) {
|
||||
return new T();
|
||||
} else {
|
||||
return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value);
|
||||
return arena->DoCreateMessage<T>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateInternal(
|
||||
Arena* arena, Args&&... args) {
|
||||
if (arena == NULL) {
|
||||
return new T(std::forward<Args>(args)...);
|
||||
} else {
|
||||
return arena->DoCreate<T>(std::is_trivially_destructible<T>::value,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
@ -696,8 +519,9 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// Allocate and also optionally call on_arena_allocation callback with the
|
||||
// allocated type info when the hooks are in place in ArenaOptions and
|
||||
// the cookie is not null.
|
||||
template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
void* AllocateInternal(bool skip_explicit_ownership) {
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void* AllocateInternal(
|
||||
bool skip_explicit_ownership) {
|
||||
const size_t n = internal::AlignUpTo8(sizeof(T));
|
||||
AllocHook(RTTI_TYPE_ID(T), n);
|
||||
// Monitor allocation if needed.
|
||||
@ -714,27 +538,49 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// as it can cause confusing API usages, and end up having double free in
|
||||
// user code. These are used only internally from LazyField and Repeated
|
||||
// fields, since they are designed to work in all mode combinations.
|
||||
template <typename Msg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static Msg* CreateMaybeMessage(Arena* arena, google::protobuf::internal::true_type) {
|
||||
return CreateMessageInternal<Msg>(arena);
|
||||
template <typename Msg, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static Msg* DoCreateMaybeMessage(
|
||||
Arena* arena, std::true_type, Args&&... args) {
|
||||
return CreateMessageInternal<Msg>(arena, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateMaybeMessage(Arena* arena, google::protobuf::internal::false_type) {
|
||||
return CreateInternal<T>(arena);
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* DoCreateMaybeMessage(
|
||||
Arena* arena, std::false_type, Args&&... args) {
|
||||
return CreateInternal<T>(arena, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static T* CreateMaybeMessage(Arena* arena) {
|
||||
return CreateMaybeMessage<T>(arena, is_arena_constructable<T>());
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateMaybeMessage(
|
||||
Arena* arena, Args&&... args) {
|
||||
return DoCreateMaybeMessage<T>(arena, is_arena_constructable<T>(),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateNoMessage(
|
||||
Arena* arena, std::true_type, Args&&... args) {
|
||||
// User is constructing with Create() despite the fact that T supports arena
|
||||
// construction. In this case we have to delegate to CreateInternal(), and
|
||||
// we can't use any CreateMaybeMessage() specialization that may be defined.
|
||||
return CreateInternal<T>(arena, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateNoMessage(
|
||||
Arena* arena, std::false_type, Args&&... args) {
|
||||
// User is constructing with Create() and the type does not support arena
|
||||
// construction. In this case we can delegate to CreateMaybeMessage() and
|
||||
// use any specialization that may be available for that.
|
||||
return CreateMaybeMessage<T>(arena, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Just allocate the required size for the given type assuming the
|
||||
// type has a trivial constructor.
|
||||
template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternalRawArray(size_t num_elements) {
|
||||
GOOGLE_CHECK_LE(num_elements,
|
||||
std::numeric_limits<size_t>::max() / sizeof(T))
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* CreateInternalRawArray(
|
||||
size_t num_elements) {
|
||||
GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T))
|
||||
<< "Requested size is too large to fit into size_t.";
|
||||
const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements);
|
||||
// Monitor allocation if needed.
|
||||
@ -742,143 +588,18 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
return static_cast<T*>(impl_.AllocateAligned(n));
|
||||
}
|
||||
|
||||
#if LANG_CXX11
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership, Args&&... args) {
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* DoCreate(
|
||||
bool skip_explicit_ownership, Args&&... args) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(std::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership)) T();
|
||||
}
|
||||
|
||||
template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3,
|
||||
const Arg4& arg4) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3,
|
||||
const Arg4& arg4,
|
||||
const Arg5& arg5) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5, typename Arg6>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3,
|
||||
const Arg4& arg4,
|
||||
const Arg5& arg5,
|
||||
const Arg6& arg6) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5, typename Arg6, typename Arg7>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3,
|
||||
const Arg4& arg4,
|
||||
const Arg5& arg5,
|
||||
const Arg6& arg6,
|
||||
const Arg7& arg7) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5, typename Arg6, typename Arg7,
|
||||
typename Arg8>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateInternal(bool skip_explicit_ownership,
|
||||
const Arg1& arg1,
|
||||
const Arg2& arg2,
|
||||
const Arg3& arg3,
|
||||
const Arg4& arg4,
|
||||
const Arg5& arg5,
|
||||
const Arg6& arg6,
|
||||
const Arg7& arg7,
|
||||
const Arg8& arg8) {
|
||||
return new (AllocateInternal<T>(skip_explicit_ownership))
|
||||
T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
#endif
|
||||
#if LANG_CXX11
|
||||
template <typename T, typename... Args>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(
|
||||
Args&&... args) {
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* DoCreateMessage(Args&&... args) {
|
||||
return InternalHelper<T>::Construct(
|
||||
AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
||||
this, std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal() {
|
||||
return InternalHelper<T>::Construct(
|
||||
AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
||||
this);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateMessageInternal(const Arg& arg) {
|
||||
return InternalHelper<T>::Construct(
|
||||
AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
||||
this, arg);
|
||||
}
|
||||
|
||||
template <typename T, typename Arg1, typename Arg2>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
T* CreateMessageInternal(const Arg1& arg1, const Arg2& arg2) {
|
||||
return InternalHelper<T>::Construct(
|
||||
AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
||||
this, arg1, arg2);
|
||||
}
|
||||
|
||||
// CreateInArenaStorage is used to implement map field. Without it,
|
||||
// google::protobuf::Map need to call generated message's protected arena constructor,
|
||||
@ -893,22 +614,22 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void CreateInArenaStorageInternal(
|
||||
T* ptr, Arena* arena, google::protobuf::internal::true_type) {
|
||||
static void CreateInArenaStorageInternal(T* ptr, Arena* arena,
|
||||
std::true_type) {
|
||||
InternalHelper<T>::Construct(ptr, arena);
|
||||
}
|
||||
template <typename T>
|
||||
static void CreateInArenaStorageInternal(
|
||||
T* ptr, Arena* /* arena */, google::protobuf::internal::false_type) {
|
||||
static void CreateInArenaStorageInternal(T* ptr, Arena* /* arena */,
|
||||
std::false_type) {
|
||||
new (ptr) T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void RegisterDestructorInternal(
|
||||
T* /* ptr */, Arena* /* arena */, google::protobuf::internal::true_type) {}
|
||||
static void RegisterDestructorInternal(T* /* ptr */, Arena* /* arena */,
|
||||
std::true_type) {}
|
||||
template <typename T>
|
||||
static void RegisterDestructorInternal(
|
||||
T* ptr, Arena* arena, google::protobuf::internal::false_type) {
|
||||
static void RegisterDestructorInternal(T* ptr, Arena* arena,
|
||||
std::false_type) {
|
||||
arena->OwnDestructor(ptr);
|
||||
}
|
||||
|
||||
@ -917,15 +638,16 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// is a subtype of ::google::protobuf::Message and 'false_type' otherwise. Collapsing
|
||||
// all template instantiations to one for generic Message reduces code size,
|
||||
// using the virtual destructor instead.
|
||||
template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
void OwnInternal(T* object, google::protobuf::internal::true_type) {
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void OwnInternal(T* object,
|
||||
std::true_type) {
|
||||
if (object != NULL) {
|
||||
impl_.AddCleanup(object,
|
||||
&internal::arena_delete_object< ::google::protobuf::Message>);
|
||||
impl_.AddCleanup(object, &internal::arena_delete_object<Message>);
|
||||
}
|
||||
}
|
||||
template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
void OwnInternal(T* object, google::protobuf::internal::false_type) {
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void OwnInternal(T* object,
|
||||
std::false_type) {
|
||||
if (object != NULL) {
|
||||
impl_.AddCleanup(object, &internal::arena_delete_object<T>);
|
||||
}
|
||||
@ -934,16 +656,15 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
// Implementation for GetArena(). Only message objects with
|
||||
// InternalArenaConstructable_ tags can be associated with an arena, and such
|
||||
// objects must implement a GetArenaNoVirtual() method.
|
||||
template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static ::google::protobuf::Arena* GetArenaInternal(
|
||||
const T* value, google::protobuf::internal::true_type) {
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static Arena* GetArenaInternal(
|
||||
const T* value, std::true_type) {
|
||||
return InternalHelper<T>::GetArena(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
||||
static ::google::protobuf::Arena* GetArenaInternal(
|
||||
const T* /* value */, google::protobuf::internal::false_type) {
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static Arena* GetArenaInternal(
|
||||
const T* /* value */, std::false_type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -965,9 +686,10 @@ class LIBPROTOBUF_EXPORT Arena {
|
||||
void* hooks_cookie_;
|
||||
|
||||
template <typename Type>
|
||||
friend class ::google::protobuf::internal::GenericTypeHandler;
|
||||
friend class internal::GenericTypeHandler;
|
||||
friend struct internal::ArenaStringPtr; // For AllocateAligned.
|
||||
friend class internal::LazyField; // For CreateMaybeMessage.
|
||||
friend class internal::LazyField; // For CreateMaybeMessage.
|
||||
friend class MessageLite;
|
||||
template <typename Key, typename T>
|
||||
friend class Map;
|
||||
};
|
||||
|
@ -33,13 +33,11 @@
|
||||
#ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__
|
||||
#define GOOGLE_PROTOBUF_ARENA_IMPL_H__
|
||||
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
|
||||
#include <google/protobuf/stubs/atomic_sequence_num.h>
|
||||
#include <google/protobuf/stubs/atomicops.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/mutex.h>
|
||||
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
|
||||
@ -248,7 +246,7 @@ class LIBPROTOBUF_EXPORT ArenaImpl {
|
||||
int64 last_lifecycle_id_seen;
|
||||
SerialArena* last_serial_arena;
|
||||
};
|
||||
static google::protobuf::internal::SequenceNumber lifecycle_id_generator_;
|
||||
static std::atomic<int64> lifecycle_id_generator_;
|
||||
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
|
||||
// Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread
|
||||
// local storage class we implemented.
|
||||
@ -277,12 +275,15 @@ class LIBPROTOBUF_EXPORT ArenaImpl {
|
||||
// TODO(haberman): evaluate whether we would gain efficiency by getting rid
|
||||
// of hint_. It's the only write we do to ArenaImpl in the allocation path,
|
||||
// which will dirty the cache line.
|
||||
google::protobuf::internal::Release_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(serial));
|
||||
|
||||
hint_.store(serial, std::memory_order_release);
|
||||
}
|
||||
|
||||
google::protobuf::internal::AtomicWord threads_; // Pointer to a linked list of SerialArena.
|
||||
google::protobuf::internal::AtomicWord hint_; // Fast thread-local block access
|
||||
google::protobuf::internal::AtomicWord space_allocated_; // Sum of sizes of all allocated blocks.
|
||||
|
||||
std::atomic<SerialArena*>
|
||||
threads_; // Pointer to a linked list of SerialArena.
|
||||
std::atomic<SerialArena*> hint_; // Fast thread-local block access
|
||||
std::atomic<size_t> space_allocated_; // Total size of all allocated blocks.
|
||||
|
||||
Block *initial_block_; // If non-NULL, points to the block that came from
|
||||
// user data.
|
||||
@ -297,18 +298,20 @@ class LIBPROTOBUF_EXPORT ArenaImpl {
|
||||
Options options_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl);
|
||||
// All protos have pointers back to the arena hence Arena must have
|
||||
// pointer stability.
|
||||
ArenaImpl(ArenaImpl&&) = delete;
|
||||
ArenaImpl& operator=(ArenaImpl&&) = delete;
|
||||
|
||||
public:
|
||||
// kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8
|
||||
// to protect the invariant that pos is always at a multiple of 8.
|
||||
static const size_t kBlockHeaderSize = (sizeof(Block) + 7) & -8;
|
||||
static const size_t kSerialArenaSize = (sizeof(SerialArena) + 7) & -8;
|
||||
#if LANG_CXX11
|
||||
static_assert(kBlockHeaderSize % 8 == 0,
|
||||
"kBlockHeaderSize must be a multiple of 8.");
|
||||
static_assert(kSerialArenaSize % 8 == 0,
|
||||
"kSerialArenaSize must be a multiple of 8.");
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -50,7 +50,7 @@ void TestParseCorruptedString(const T& message) {
|
||||
s[i] ^= c;
|
||||
google::protobuf::Arena arena;
|
||||
T* message =
|
||||
google::protobuf::Arena::CreateMessage<T>(use_arena ? &arena : NULL);
|
||||
google::protobuf::Arena::CreateMessage<T>(use_arena ? &arena : nullptr);
|
||||
if (message->ParseFromString(s)) {
|
||||
++success_count;
|
||||
}
|
||||
|
@ -33,10 +33,8 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
@ -153,9 +151,19 @@ class MustBeConstructedWithOneThroughEight {
|
||||
TEST(ArenaTest, ArenaConstructable) {
|
||||
EXPECT_TRUE(Arena::is_arena_constructable<TestAllTypes>::type::value);
|
||||
EXPECT_TRUE(Arena::is_arena_constructable<const TestAllTypes>::type::value);
|
||||
EXPECT_FALSE(Arena::is_arena_constructable<
|
||||
protobuf_unittest_no_arena::TestNoArenaMessage>::type::value);
|
||||
EXPECT_FALSE(Arena::is_arena_constructable<Arena>::type::value);
|
||||
}
|
||||
|
||||
TEST(ArenaTest, DestructorSkippable) {
|
||||
EXPECT_TRUE(Arena::is_destructor_skippable<TestAllTypes>::type::value);
|
||||
EXPECT_TRUE(Arena::is_destructor_skippable<const TestAllTypes>::type::value);
|
||||
EXPECT_FALSE(Arena::is_destructor_skippable<
|
||||
protobuf_unittest_no_arena::TestNoArenaMessage>::type::value);
|
||||
EXPECT_FALSE(Arena::is_destructor_skippable<Arena>::type::value);
|
||||
}
|
||||
|
||||
TEST(ArenaTest, BasicCreate) {
|
||||
Arena arena;
|
||||
EXPECT_TRUE(Arena::Create<int32>(&arena) != NULL);
|
||||
@ -197,7 +205,6 @@ TEST(ArenaTest, CreateAndNonConstCopy) {
|
||||
EXPECT_EQ("foo", *s_copy);
|
||||
}
|
||||
|
||||
#if LANG_CXX11
|
||||
TEST(ArenaTest, CreateAndMove) {
|
||||
Arena arena;
|
||||
string s("foo");
|
||||
@ -206,7 +213,6 @@ TEST(ArenaTest, CreateAndMove) {
|
||||
EXPECT_TRUE(s.empty()); // NOLINT
|
||||
EXPECT_EQ("foo", *s_move);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(ArenaTest, CreateWithFourConstructorArguments) {
|
||||
Arena arena;
|
||||
@ -242,7 +248,6 @@ TEST(ArenaTest, CreateWithEightConstructorArguments) {
|
||||
ASSERT_EQ("8", new_object->eight_);
|
||||
}
|
||||
|
||||
#if LANG_CXX11
|
||||
class PleaseMoveMe {
|
||||
public:
|
||||
explicit PleaseMoveMe(const string& value) : value_(value) {}
|
||||
@ -263,7 +268,6 @@ TEST(ArenaTest, CreateWithMoveArguments) {
|
||||
EXPECT_TRUE(new_object);
|
||||
ASSERT_EQ("1", new_object->value());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(ArenaTest, InitialBlockTooSmall) {
|
||||
// Construct a small (64 byte) initial block of memory to be used by the
|
||||
@ -442,7 +446,7 @@ TEST(ArenaTest, ReflectionSwapFields) {
|
||||
TestUtil::SetAllFields(arena1_message);
|
||||
reflection->SwapFields(arena1_message, &message, fields);
|
||||
EXPECT_EQ(&arena1, arena1_message->GetArena());
|
||||
EXPECT_EQ(NULL, message.GetArena());
|
||||
EXPECT_EQ(nullptr, message.GetArena());
|
||||
arena1_message->SerializeToString(&output);
|
||||
EXPECT_EQ(0, output.size());
|
||||
TestUtil::ExpectAllFieldsSet(message);
|
||||
@ -468,7 +472,7 @@ TEST(ArenaTest, ReleaseMessage) {
|
||||
Arena arena;
|
||||
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
|
||||
arena_message->mutable_optional_nested_message()->set_bb(118);
|
||||
google::protobuf::scoped_ptr<TestAllTypes::NestedMessage> nested(
|
||||
std::unique_ptr<TestAllTypes::NestedMessage> nested(
|
||||
arena_message->release_optional_nested_message());
|
||||
EXPECT_EQ(118, nested->bb());
|
||||
|
||||
@ -489,7 +493,7 @@ TEST(ArenaTest, ReleaseString) {
|
||||
Arena arena;
|
||||
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
|
||||
arena_message->set_optional_string("hello");
|
||||
google::protobuf::scoped_ptr<string> released_str(
|
||||
std::unique_ptr<string> released_str(
|
||||
arena_message->release_optional_string());
|
||||
EXPECT_EQ("hello", *released_str);
|
||||
|
||||
@ -600,25 +604,6 @@ TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
|
||||
}
|
||||
#endif // !GOOGLE_PROTOBUF_NO_RTTI
|
||||
|
||||
TEST(ArenaTest, UnsafeArenaReleaseDoesNotMakeCopy) {
|
||||
Arena arena;
|
||||
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
|
||||
TestAllTypes::NestedMessage* nested_msg = NULL;
|
||||
TestAllTypes::NestedMessage* orig_nested_msg = NULL;
|
||||
string* nested_string = NULL;
|
||||
string* orig_nested_string = NULL;
|
||||
arena_message->mutable_optional_nested_message()->set_bb(42);
|
||||
*arena_message->mutable_optional_string() = "Hello";
|
||||
orig_nested_msg = arena_message->mutable_optional_nested_message();
|
||||
orig_nested_string = arena_message->mutable_optional_string();
|
||||
nested_msg = arena_message->unsafe_arena_release_optional_nested_message();
|
||||
nested_string = arena_message->unsafe_arena_release_optional_string();
|
||||
|
||||
EXPECT_EQ(orig_nested_msg, nested_msg);
|
||||
EXPECT_EQ(orig_nested_string, nested_string);
|
||||
// Released pointers still on arena; no 'delete' calls needed here.
|
||||
}
|
||||
|
||||
TEST(ArenaTest, SetAllocatedAcrossArenas) {
|
||||
Arena arena1;
|
||||
TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
|
||||
@ -898,17 +883,18 @@ TEST(ArenaTest, ReleaseLastRepeatedField) {
|
||||
TEST(ArenaTest, UnsafeArenaReleaseAdd) {
|
||||
// Use unsafe_arena_release() and unsafe_arena_set_allocated() to transfer an
|
||||
// arena-allocated string from one message to another.
|
||||
const char kContent[] = "Test content";
|
||||
|
||||
Arena arena;
|
||||
TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
|
||||
TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&arena);
|
||||
string* arena_string = Arena::Create<string>(&arena);
|
||||
*arena_string = "Test content";
|
||||
*arena_string = kContent;
|
||||
|
||||
message1->unsafe_arena_set_allocated_optional_string(arena_string);
|
||||
EXPECT_EQ(arena_string, message1->mutable_optional_string());
|
||||
message2->unsafe_arena_set_allocated_optional_string(
|
||||
message1->unsafe_arena_release_optional_string());
|
||||
EXPECT_EQ(arena_string, message2->mutable_optional_string());
|
||||
EXPECT_EQ(kContent, message2->optional_string());
|
||||
}
|
||||
|
||||
TEST(ArenaTest, UnsafeArenaAddAllocated) {
|
||||
@ -1432,7 +1418,7 @@ TEST(ArenaTest, ArenaHooksSanity) {
|
||||
EXPECT_EQ(1, ArenaHooksTestUtil::num_init);
|
||||
EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations);
|
||||
::google::protobuf::Arena::Create<uint64>(&arena);
|
||||
if (google::protobuf::internal::has_trivial_destructor<uint64>::value) {
|
||||
if (std::is_trivially_destructible<uint64>::value) {
|
||||
EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations);
|
||||
} else {
|
||||
EXPECT_EQ(2, ArenaHooksTestUtil::num_allocations);
|
||||
|
@ -99,6 +99,13 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
if (ptr_ == default_value) {
|
||||
return NULL;
|
||||
}
|
||||
return ReleaseNonDefault(default_value, arena);
|
||||
}
|
||||
|
||||
// Similar to Release, but ptr_ cannot be the default_value.
|
||||
inline ::std::string* ReleaseNonDefault(
|
||||
const ::std::string* default_value, ::google::protobuf::Arena* arena) {
|
||||
GOOGLE_DCHECK(!IsDefault(default_value));
|
||||
::std::string* released = NULL;
|
||||
if (arena != NULL) {
|
||||
// ptr_ is owned by the arena.
|
||||
@ -164,6 +171,29 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) {
|
||||
std::swap(ptr_, other->ptr_);
|
||||
}
|
||||
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(
|
||||
ArenaStringPtr* other, const ::std::string* default_value, Arena* arena) {
|
||||
#ifndef NDEBUG
|
||||
// For debug builds, we swap the contents of the string, rather than the
|
||||
// string instances themselves. This invalidates previously taken const
|
||||
// references that are (per our documentation) invalidated by calling Swap()
|
||||
// on the message.
|
||||
//
|
||||
// If both strings are the default_value, swapping is uninteresting.
|
||||
// Otherwise, we use ArenaStringPtr::Mutable() to access the string, to
|
||||
// ensure that we do not try to mutate default_value itself.
|
||||
if (IsDefault(default_value) && other->IsDefault(default_value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
::std::string* this_ptr = Mutable(default_value, arena);
|
||||
::std::string* other_ptr = other->Mutable(default_value, arena);
|
||||
|
||||
this_ptr->swap(*other_ptr);
|
||||
#else
|
||||
std::swap(ptr_, other->ptr_);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Frees storage (if not on an arena).
|
||||
inline void Destroy(const ::std::string* default_value,
|
||||
@ -186,6 +216,15 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
}
|
||||
}
|
||||
|
||||
// Clears content, assuming that the current value is not the empty string
|
||||
// default.
|
||||
inline void ClearNonDefaultToEmpty() {
|
||||
ptr_->clear();
|
||||
}
|
||||
inline void ClearNonDefaultToEmptyNoArena() {
|
||||
ptr_->clear();
|
||||
}
|
||||
|
||||
// Clears content, but keeps allocated string if arena != NULL, to avoid the
|
||||
// overhead of heap operations. After this returns, the content (as seen by
|
||||
// the user) will always be equal to |default_value|.
|
||||
@ -253,12 +292,19 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
|
||||
if (ptr_ == default_value) {
|
||||
return NULL;
|
||||
} else {
|
||||
::std::string* released = ptr_;
|
||||
ptr_ = const_cast< ::std::string* >(default_value);
|
||||
return released;
|
||||
return ReleaseNonDefaultNoArena(default_value);
|
||||
}
|
||||
}
|
||||
|
||||
inline ::std::string* ReleaseNonDefaultNoArena(
|
||||
const ::std::string* default_value) {
|
||||
GOOGLE_DCHECK(!IsDefault(default_value));
|
||||
::std::string* released = ptr_;
|
||||
ptr_ = const_cast< ::std::string* >(default_value);
|
||||
return released;
|
||||
}
|
||||
|
||||
|
||||
inline void SetAllocatedNoArena(const ::std::string* default_value,
|
||||
::std::string* value) {
|
||||
if (ptr_ != default_value) {
|
||||
|
@ -35,9 +35,6 @@
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -31,9 +31,6 @@
|
||||
#include <google/protobuf/compiler/annotation_test_util.h>
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/compiler/command_line_interface.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
@ -34,9 +34,9 @@
|
||||
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
|
||||
#include <google/protobuf/compiler/plugin.pb.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/compiler/plugin.pb.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
|
@ -58,9 +58,6 @@
|
||||
#include <limits.h> //For PATH_MAX
|
||||
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
@ -171,8 +168,7 @@ 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.
|
||||
std::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];
|
||||
@ -440,7 +436,7 @@ class CommandLineInterface::MemoryOutputStream
|
||||
bool append_mode_;
|
||||
|
||||
// StringOutputStream writing to data_.
|
||||
google::protobuf::scoped_ptr<io::StringOutputStream> inner_;
|
||||
std::unique_ptr<io::StringOutputStream> inner_;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -835,10 +831,10 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
||||
|
||||
std::vector<const FileDescriptor*> parsed_files;
|
||||
// null unless descriptor_set_in_names_.empty()
|
||||
google::protobuf::scoped_ptr<DiskSourceTree> disk_source_tree;
|
||||
google::protobuf::scoped_ptr<ErrorPrinter> error_collector;
|
||||
google::protobuf::scoped_ptr<DescriptorPool> descriptor_pool;
|
||||
google::protobuf::scoped_ptr<DescriptorDatabase> descriptor_database;
|
||||
std::unique_ptr<DiskSourceTree> disk_source_tree;
|
||||
std::unique_ptr<ErrorPrinter> error_collector;
|
||||
std::unique_ptr<DescriptorPool> descriptor_pool;
|
||||
std::unique_ptr<DescriptorDatabase> descriptor_database;
|
||||
if (descriptor_set_in_names_.empty()) {
|
||||
disk_source_tree.reset(new DiskSourceTree());
|
||||
if (!InitializeDiskSourceTree(disk_source_tree.get())) {
|
||||
@ -1395,8 +1391,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
// with colons. Let's accept that syntax too just to make things more
|
||||
// intuitive.
|
||||
std::vector<string> parts = Split(
|
||||
value,
|
||||
CommandLineInterface::kPathSeparator,
|
||||
value, CommandLineInterface::kPathSeparator,
|
||||
true);
|
||||
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
@ -1421,7 +1416,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
|
||||
// Make sure disk path exists, warn otherwise.
|
||||
if (access(disk_path.c_str(), F_OK) < 0) {
|
||||
// Try the original path; it may have just happed to have a '=' in it.
|
||||
// Try the original path; it may have just happened to have a '=' in it.
|
||||
if (access(parts[i].c_str(), F_OK) < 0) {
|
||||
std::cerr << disk_path << ": warning: directory does not exist."
|
||||
<< std::endl;
|
||||
@ -1447,8 +1442,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
}
|
||||
|
||||
direct_dependencies_explicitly_set_ = true;
|
||||
std::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());
|
||||
|
||||
@ -1481,9 +1475,8 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
}
|
||||
|
||||
descriptor_set_in_names_ = Split(
|
||||
value,
|
||||
CommandLineInterface::kPathSeparator,
|
||||
true);
|
||||
value, CommandLineInterface::kPathSeparator,
|
||||
true);
|
||||
|
||||
} else if (name == "-o" || name == "--descriptor_set_out") {
|
||||
if (!descriptor_set_out_name_.empty()) {
|
||||
@ -1629,7 +1622,6 @@ CommandLineInterface::InterpretArgument(const string& name,
|
||||
}
|
||||
mode_ = MODE_PRINT;
|
||||
print_mode_ = PRINT_FREE_FIELDS;
|
||||
} else if (name == "--profile_path") {
|
||||
} else {
|
||||
// Some other flag. Look it up in the generators list.
|
||||
const GeneratorInfo* generator_info =
|
||||
@ -1908,10 +1900,12 @@ bool CommandLineInterface::GeneratePluginOutput(
|
||||
string* error) {
|
||||
CodeGeneratorRequest request;
|
||||
CodeGeneratorResponse response;
|
||||
string processed_parameter = parameter;
|
||||
|
||||
|
||||
// Build the request.
|
||||
if (!parameter.empty()) {
|
||||
request.set_parameter(parameter);
|
||||
if (!processed_parameter.empty()) {
|
||||
request.set_parameter(processed_parameter);
|
||||
}
|
||||
|
||||
|
||||
@ -1948,17 +1942,18 @@ bool CommandLineInterface::GeneratePluginOutput(
|
||||
|
||||
// Write the files. We do this even if there was a generator error in order
|
||||
// to match the behavior of a compiled-in generator.
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> current_output;
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> current_output;
|
||||
for (int i = 0; i < response.file_size(); i++) {
|
||||
const CodeGeneratorResponse::File& output_file = response.file(i);
|
||||
|
||||
if (!output_file.insertion_point().empty()) {
|
||||
string filename = output_file.name();
|
||||
// Open a file for insert.
|
||||
// We reset current_output to NULL first so that the old file is closed
|
||||
// before the new one is opened.
|
||||
current_output.reset();
|
||||
current_output.reset(generator_context->OpenForInsert(
|
||||
output_file.name(), output_file.insertion_point()));
|
||||
filename, output_file.insertion_point()));
|
||||
} else if (!output_file.name().empty()) {
|
||||
// Starting a new file. Open it.
|
||||
// We reset current_output to NULL first so that the old file is closed
|
||||
@ -1997,7 +1992,7 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
|
||||
}
|
||||
|
||||
DynamicMessageFactory dynamic_factory(pool);
|
||||
google::protobuf::scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
|
||||
std::unique_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
|
||||
|
||||
if (mode_ == MODE_ENCODE) {
|
||||
SetFdToTextMode(STDIN_FILENO);
|
||||
|
@ -413,11 +413,6 @@ class LIBPROTOC_EXPORT CommandLineInterface {
|
||||
// dependency file will be written. Otherwise, empty.
|
||||
string dependency_out_name_;
|
||||
|
||||
// Path to a file that contains serialized AccessInfo which provides
|
||||
// relative hotness of fields per message. This helps protoc to generate
|
||||
// better code.
|
||||
string profile_path_;
|
||||
|
||||
// True if --include_imports was given, meaning that we should
|
||||
// write all transitive dependencies to the DescriptorSet. Otherwise, only
|
||||
// the .proto files listed on the command-line are added.
|
||||
|
@ -40,9 +40,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/stubs/stringprintf.h>
|
||||
@ -344,7 +341,7 @@ void CommandLineInterfaceTest::RunWithArgs(std::vector<string> args) {
|
||||
}
|
||||
}
|
||||
|
||||
google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]);
|
||||
std::unique_ptr<const char * []> argv(new const char* [args.size()]);
|
||||
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
|
||||
@ -2298,7 +2295,7 @@ class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
|
||||
ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam();
|
||||
}
|
||||
|
||||
google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]);
|
||||
std::unique_ptr<const char * []> argv(new const char* [args.size()]);
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
argv[i] = args[i].c_str();
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_generator.h>
|
||||
#include <google/protobuf/compiler/importer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
@ -97,9 +98,10 @@ class MockGeneratorContext : public GeneratorContext {
|
||||
File::GetContents(TestSourceDir() + "/" + physical_filename,
|
||||
&actual_contents, true));
|
||||
EXPECT_TRUE(actual_contents == *expected_contents)
|
||||
<< physical_filename << " needs to be regenerated. Please run "
|
||||
"generate_descriptor_proto.sh. Then add this file "
|
||||
"to your CL.";
|
||||
<< physical_filename
|
||||
<< " needs to be regenerated. Please run "
|
||||
"generate_descriptor_proto.sh. "
|
||||
"Then add this file to your CL.";
|
||||
}
|
||||
|
||||
// implements GeneratorContext --------------------------------------
|
||||
@ -116,37 +118,50 @@ class MockGeneratorContext : public GeneratorContext {
|
||||
std::map<string, string*> files_;
|
||||
};
|
||||
|
||||
TEST(BootstrapTest, GeneratedDescriptorMatches) {
|
||||
MockErrorCollector error_collector;
|
||||
const char kDescriptorParameter[] = "dllexport_decl=LIBPROTOBUF_EXPORT";
|
||||
const char kPluginParameter[] = "dllexport_decl=LIBPROTOC_EXPORT";
|
||||
const char kNormalParameter[] = "";
|
||||
|
||||
const char* test_protos[][2] = {
|
||||
{"google/protobuf/descriptor", kDescriptorParameter},
|
||||
{"google/protobuf/compiler/plugin", kPluginParameter},
|
||||
};
|
||||
|
||||
TEST(BootstrapTest, GeneratedFilesMatch) {
|
||||
// We need a mapping from the actual file to virtual and actual path
|
||||
// of the data to compare to.
|
||||
std::map<string, string> vpath_map;
|
||||
std::map<string, string> rpath_map;
|
||||
rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto2"] =
|
||||
"net/proto2/z_generated_example/test_messages_proto2";
|
||||
rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] =
|
||||
"net/proto2/z_generated_example/test_messages_proto3";
|
||||
rpath_map["google/protobuf/proto2_weak"] =
|
||||
"net/proto2/z_generated_example/proto2_weak";
|
||||
|
||||
DiskSourceTree source_tree;
|
||||
source_tree.MapPath("", TestSourceDir());
|
||||
Importer importer(&source_tree, &error_collector);
|
||||
const FileDescriptor* proto_file =
|
||||
importer.Import("google/protobuf/descriptor.proto");
|
||||
const FileDescriptor* plugin_proto_file =
|
||||
importer.Import("google/protobuf/compiler/plugin.proto");
|
||||
EXPECT_EQ("", error_collector.text_);
|
||||
ASSERT_TRUE(proto_file != NULL);
|
||||
ASSERT_TRUE(plugin_proto_file != NULL);
|
||||
|
||||
CppGenerator generator;
|
||||
MockGeneratorContext context;
|
||||
string error;
|
||||
string parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
|
||||
ASSERT_TRUE(generator.Generate(proto_file, parameter,
|
||||
&context, &error));
|
||||
parameter = "dllexport_decl=LIBPROTOC_EXPORT";
|
||||
ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
|
||||
&context, &error));
|
||||
for (auto file_parameter : test_protos) {
|
||||
MockErrorCollector error_collector;
|
||||
Importer importer(&source_tree, &error_collector);
|
||||
const FileDescriptor* file =
|
||||
importer.Import(file_parameter[0] + string(".proto"));
|
||||
ASSERT_TRUE(file != nullptr)
|
||||
<< "Can't import file " << file_parameter[0] + string(".proto") << "\n";
|
||||
EXPECT_EQ("", error_collector.text_);
|
||||
CppGenerator generator;
|
||||
MockGeneratorContext context;
|
||||
string error;
|
||||
ASSERT_TRUE(generator.Generate(file, file_parameter[1], &context, &error));
|
||||
|
||||
context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
|
||||
"google/protobuf/descriptor.pb.h");
|
||||
context.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
|
||||
"google/protobuf/descriptor.pb.cc");
|
||||
context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
|
||||
"google/protobuf/compiler/plugin.pb.h");
|
||||
context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
|
||||
"google/protobuf/compiler/plugin.pb.cc");
|
||||
string vpath =
|
||||
FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]);
|
||||
string rpath =
|
||||
FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]);
|
||||
context.ExpectFileMatches(vpath + ".pb.cc", rpath + ".pb.cc");
|
||||
context.ExpectFileMatches(vpath + ".pb.h", rpath + ".pb.h");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -179,7 +179,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
void EnumGenerator::
|
||||
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
|
||||
printer->Print(
|
||||
"template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type "
|
||||
"template <> struct is_proto_enum< $classname$> : ::std::true_type "
|
||||
"{};\n",
|
||||
"classname", ClassName(descriptor_, true));
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
|
@ -35,8 +35,8 @@
|
||||
#include <google/protobuf/compiler/cpp/cpp_extension.h>
|
||||
#include <map>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
|
||||
@ -120,7 +120,6 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
|
||||
" ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
|
||||
" $name$;\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
|
@ -34,21 +34,18 @@
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_field.h>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_map_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
namespace google {
|
||||
@ -116,26 +113,30 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
|
||||
}
|
||||
|
||||
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
|
||||
const Options& options)
|
||||
const Options& options,
|
||||
SCCAnalyzer* scc_analyzer)
|
||||
: descriptor_(descriptor),
|
||||
options_(options),
|
||||
field_generators_(
|
||||
new google::protobuf::scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
|
||||
new std::unique_ptr<FieldGenerator>[descriptor->field_count()]) {
|
||||
// Construct all the FieldGenerators.
|
||||
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||
field_generators_[i].reset(MakeGenerator(descriptor->field(i), options));
|
||||
field_generators_[i].reset(
|
||||
MakeGenerator(descriptor->field(i), options, scc_analyzer));
|
||||
}
|
||||
}
|
||||
|
||||
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
|
||||
const Options& options) {
|
||||
const Options& options,
|
||||
SCCAnalyzer* scc_analyzer) {
|
||||
if (field->is_repeated()) {
|
||||
switch (field->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
if (field->is_map()) {
|
||||
return new MapFieldGenerator(field, options);
|
||||
} else {
|
||||
return new RepeatedMessageFieldGenerator(field, options);
|
||||
return new RepeatedMessageFieldGenerator(field, options,
|
||||
scc_analyzer);
|
||||
}
|
||||
case FieldDescriptor::CPPTYPE_STRING:
|
||||
switch (field->options().ctype()) {
|
||||
@ -151,7 +152,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
|
||||
} else if (field->containing_oneof()) {
|
||||
switch (field->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
return new MessageOneofFieldGenerator(field, options);
|
||||
return new MessageOneofFieldGenerator(field, options, scc_analyzer);
|
||||
case FieldDescriptor::CPPTYPE_STRING:
|
||||
switch (field->options().ctype()) {
|
||||
default: // StringOneofFieldGenerator handles unknown ctypes.
|
||||
@ -166,7 +167,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
|
||||
} else {
|
||||
switch (field->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
return new MessageFieldGenerator(field, options);
|
||||
return new MessageFieldGenerator(field, options, scc_analyzer);
|
||||
case FieldDescriptor::CPPTYPE_STRING:
|
||||
switch (field->options().ctype()) {
|
||||
default: // StringFieldGenerator handles unknown ctypes.
|
||||
|
@ -37,13 +37,11 @@
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_options.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -82,38 +80,12 @@ class FieldGenerator {
|
||||
// implementation is empty.
|
||||
virtual void GenerateStaticMembers(io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate prototypes for accessors that will manipulate imported
|
||||
// messages inline. These are for .proto.h headers.
|
||||
//
|
||||
// In .proto.h mode, the headers of imports are not #included. However,
|
||||
// functions that manipulate the imported message types need access to
|
||||
// the class definition of the imported message, meaning that the headers
|
||||
// must be #included. To get around this, functions that manipulate
|
||||
// imported message objects are defined as dependent functions in a base
|
||||
// template class. By making them dependent template functions, the
|
||||
// function templates will not be instantiated until they are called, so
|
||||
// we can defer to those translation units to #include the necessary
|
||||
// generated headers.
|
||||
//
|
||||
// See:
|
||||
// http://en.cppreference.com/w/cpp/language/class_template#Implicit_instantiation
|
||||
//
|
||||
// Most field types don't need this, so the default implementation is empty.
|
||||
virtual void GenerateDependentAccessorDeclarations(
|
||||
io::Printer* printer) const {}
|
||||
|
||||
// Generate prototypes for all of the accessor functions related to this
|
||||
// field. These are placed inside the class definition.
|
||||
virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate inline definitions of depenent accessor functions for this field.
|
||||
// These are placed inside the header after all class definitions.
|
||||
virtual void GenerateDependentInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {}
|
||||
|
||||
// Generate inline definitions of accessor functions for this field.
|
||||
// These are placed inside the header after all class definitions.
|
||||
// In non-.proto.h mode, this generates dependent accessor functions as well.
|
||||
virtual void GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const = 0;
|
||||
|
||||
@ -207,6 +179,11 @@ class FieldGenerator {
|
||||
// are placed in the message's ByteSize() method.
|
||||
virtual void GenerateByteSize(io::Printer* printer) const = 0;
|
||||
|
||||
// Any tags about field layout decisions (such as inlining) to embed in the
|
||||
// offset.
|
||||
virtual uint32 CalculateFieldTag() const { return 0; }
|
||||
virtual bool IsInlined() const { return false; }
|
||||
|
||||
protected:
|
||||
const Options& options_;
|
||||
|
||||
@ -217,7 +194,8 @@ class FieldGenerator {
|
||||
// Convenience class which constructs FieldGenerators for a Descriptor.
|
||||
class FieldGeneratorMap {
|
||||
public:
|
||||
FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
|
||||
FieldGeneratorMap(const Descriptor* descriptor, const Options& options,
|
||||
SCCAnalyzer* scc_analyzer);
|
||||
~FieldGeneratorMap();
|
||||
|
||||
const FieldGenerator& get(const FieldDescriptor* field) const;
|
||||
@ -225,10 +203,11 @@ class FieldGeneratorMap {
|
||||
private:
|
||||
const Descriptor* descriptor_;
|
||||
const Options& options_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<FieldGenerator> > field_generators_;
|
||||
std::unique_ptr<std::unique_ptr<FieldGenerator> []> field_generators_;
|
||||
|
||||
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
const Options& options,
|
||||
SCCAnalyzer* scc_analyzer);
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
|
||||
};
|
||||
|
@ -35,20 +35,17 @@
|
||||
#include <google/protobuf/compiler/cpp/cpp_file.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_enum.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_service.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_extension.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_message.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_field.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_service.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
namespace google {
|
||||
@ -61,11 +58,11 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
|
||||
options_(options),
|
||||
scc_analyzer_(options),
|
||||
enum_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]),
|
||||
new std::unique_ptr<EnumGenerator>[file->enum_type_count()]),
|
||||
service_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
|
||||
new std::unique_ptr<ServiceGenerator>[file->service_count()]),
|
||||
extension_generators_owner_(
|
||||
new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) {
|
||||
new std::unique_ptr<ExtensionGenerator>[file->extension_count()]) {
|
||||
std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file);
|
||||
for (int i = 0; i < msgs.size(); i++) {
|
||||
// Deleted in destructor
|
||||
@ -141,6 +138,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
|
||||
printer->Print(
|
||||
"// @@protoc_insertion_point(includes)\n");
|
||||
|
||||
printer->Print("#define PROTOBUF_INTERNAL_EXPORT_$filename$ $export$\n",
|
||||
"filename", FileLevelNamespace(file_),
|
||||
"export", options_.dllexport_decl);
|
||||
GenerateMacroUndefs(printer);
|
||||
|
||||
GenerateGlobalStateFunctionDeclarations(printer);
|
||||
@ -223,8 +223,9 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer,
|
||||
GenerateTopHeaderGuard(printer, filename_identifier);
|
||||
|
||||
if (options_.proto_h) {
|
||||
string target_basename = StripProto(file_->name());
|
||||
printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n",
|
||||
"basename", StripProto(file_->name()));
|
||||
"basename", target_basename);
|
||||
} else {
|
||||
GenerateLibraryIncludes(printer);
|
||||
}
|
||||
@ -256,9 +257,10 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer,
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
|
||||
string target_basename = StripProto(file_->name());
|
||||
const bool use_system_include = IsWellKnownMessage(file_);
|
||||
string header =
|
||||
StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h");
|
||||
|
||||
string header = target_basename + (options_.proto_h ? ".proto.h" : ".pb.h");
|
||||
printer->Print(
|
||||
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
|
||||
"// source: $filename$\n"
|
||||
@ -269,7 +271,6 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
|
||||
"\n"
|
||||
"#include <google/protobuf/stubs/common.h>\n"
|
||||
"#include <google/protobuf/stubs/port.h>\n"
|
||||
"#include <google/protobuf/stubs/once.h>\n"
|
||||
"#include <google/protobuf/io/coded_stream.h>\n"
|
||||
"#include <google/protobuf/wire_format_lite_inl.h>\n",
|
||||
"filename", file_->name(),
|
||||
@ -296,7 +297,8 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
|
||||
for (int i = 0; i < file_->dependency_count(); i++) {
|
||||
const FileDescriptor* dep = file_->dependency(i);
|
||||
const char* extension = ".proto.h";
|
||||
string dependency = StripProto(dep->name()) + extension;
|
||||
string basename = StripProto(dep->name());
|
||||
string dependency = basename + extension;
|
||||
printer->Print(
|
||||
"#include \"$dependency$\"\n",
|
||||
"dependency", dependency);
|
||||
@ -338,33 +340,34 @@ namespace {
|
||||
|
||||
// Generates weak symbol declarations for types that are to be considered weakly
|
||||
// referenced.
|
||||
void GenerateWeakDeclarations(
|
||||
const FileDescriptor* file, const Options& options,
|
||||
SCCAnalyzer* scc_analyzer,
|
||||
io::Printer* printer) {
|
||||
std::vector<const FieldDescriptor*> fields;
|
||||
ListAllFields(file, &fields);
|
||||
|
||||
void GenerateInternalForwardDeclarations(
|
||||
const std::vector<const FieldDescriptor*>& fields, const Options& options,
|
||||
SCCAnalyzer* scc_analyzer, io::Printer* printer) {
|
||||
// To ensure determinism and minimize the number of namespace statements,
|
||||
// we output the forward declarations sorted on namespace and type / function
|
||||
// name.
|
||||
std::set<std::pair<string, string> > messages;
|
||||
std::set<std::pair<string, string> > sccs;
|
||||
std::set<std::pair<string, string> > inits;
|
||||
for (int i = 0; i < fields.size(); ++i) {
|
||||
const FieldDescriptor* field = fields[i];
|
||||
bool is_weak = IsImplicitWeakField(field, options);
|
||||
const Descriptor* msg = field->message_type();
|
||||
if (msg == nullptr) continue;
|
||||
bool is_weak = IsImplicitWeakField(field, options, scc_analyzer);
|
||||
string flns = FileLevelNamespace(msg);
|
||||
auto scc = scc_analyzer->GetSCC(msg);
|
||||
string repr = ClassName(scc->GetRepresentative());
|
||||
string weak_attr;
|
||||
if (is_weak) {
|
||||
const Descriptor* msg = field->message_type();
|
||||
string flns = FileLevelNamespace(msg);
|
||||
string repr = ClassName(scc_analyzer->GetSCC(msg)->GetRepresentative());
|
||||
inits.insert(std::make_pair(flns, "InitDefaults" + repr));
|
||||
inits.insert(std::make_pair(flns, "AddDescriptors"));
|
||||
messages.insert(std::make_pair(Namespace(msg), ClassName(msg)));
|
||||
weak_attr = " __attribute__((weak))";
|
||||
}
|
||||
}
|
||||
|
||||
if (messages.empty()) {
|
||||
return;
|
||||
string dllexport = "PROTOBUF_INTERNAL_EXPORT_" + FileLevelNamespace(msg);
|
||||
sccs.insert(std::make_pair(flns, "extern " + dllexport + weak_attr +
|
||||
" ::google::protobuf::internal::SCCInfo<" +
|
||||
SimpleItoa(scc->children.size()) +
|
||||
"> scc_info_" + repr + ";\n"));
|
||||
}
|
||||
|
||||
printer->Print("\n");
|
||||
@ -384,13 +387,33 @@ void GenerateWeakDeclarations(
|
||||
printer->Print("void $name$() __attribute__((weak));\n",
|
||||
"name", it->second);
|
||||
}
|
||||
for (const auto& p : sccs) {
|
||||
ns.ChangeTo(p.first);
|
||||
printer->Print(p.second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
|
||||
GenerateSourceIncludes(printer);
|
||||
GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer);
|
||||
|
||||
// Generate weak declarations. We do this for the whole strongly-connected
|
||||
// component (SCC), because we have a single InitDefaults* function for the
|
||||
// SCC.
|
||||
std::vector<const FieldDescriptor*> fields;
|
||||
for (const Descriptor* message :
|
||||
scc_analyzer_.GetSCC(message_generators_[idx]->descriptor_)
|
||||
->descriptors) {
|
||||
ListAllFields(message, &fields);
|
||||
}
|
||||
GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_,
|
||||
printer);
|
||||
|
||||
if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) {
|
||||
NamespaceOpener ns(FileLevelNamespace(file_), printer);
|
||||
GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer);
|
||||
}
|
||||
|
||||
{ // package namespace
|
||||
NamespaceOpener ns(Namespace(file_), printer);
|
||||
@ -411,12 +434,6 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
|
||||
"// @@protoc_insertion_point(namespace_scope)\n");
|
||||
} // end package namespace
|
||||
|
||||
if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) {
|
||||
NamespaceOpener ns(FileLevelNamespace(file_), printer);
|
||||
GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer);
|
||||
}
|
||||
|
||||
|
||||
printer->Print(
|
||||
"namespace google {\nnamespace protobuf {\n");
|
||||
message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
|
||||
@ -430,15 +447,16 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
|
||||
|
||||
void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
|
||||
GenerateSourceIncludes(printer);
|
||||
GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer);
|
||||
|
||||
// TODO(gerbens) Generate tables here
|
||||
|
||||
// Define the code to initialize reflection. This code uses a global
|
||||
// constructor to register reflection data with the runtime pre-main.
|
||||
if (HasDescriptorMethods(file_, options_)) {
|
||||
{
|
||||
NamespaceOpener ns(FileLevelNamespace(file_), printer);
|
||||
GenerateReflectionInitializationCode(printer);
|
||||
GenerateTables(printer);
|
||||
|
||||
// Define the code to initialize reflection. This code uses a global
|
||||
// constructor to register reflection data with the runtime pre-main.
|
||||
if (HasDescriptorMethods(file_, options_)) {
|
||||
GenerateReflectionInitializationCode(printer);
|
||||
}
|
||||
}
|
||||
|
||||
NamespaceOpener ns(Namespace(file_), printer);
|
||||
@ -466,7 +484,10 @@ void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
|
||||
|
||||
void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
GenerateSourceIncludes(printer);
|
||||
GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer);
|
||||
std::vector<const FieldDescriptor*> fields;
|
||||
ListAllFields(file_, &fields);
|
||||
GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_,
|
||||
printer);
|
||||
|
||||
{
|
||||
NamespaceOpener ns(Namespace(file_), printer);
|
||||
@ -483,9 +504,25 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
|
||||
|
||||
{
|
||||
NamespaceOpener ns(FileLevelNamespace(file_), printer);
|
||||
// Define the initialization code to initialize the default instances.
|
||||
// This code doesn't use a global constructor.
|
||||
GenerateInitializationCode(printer);
|
||||
GenerateTables(printer);
|
||||
|
||||
// Now generate the InitDefaults for each SCC.
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (IsSCCRepresentative(message_generators_[i]->descriptor_)) {
|
||||
GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_),
|
||||
printer);
|
||||
}
|
||||
}
|
||||
|
||||
printer->Print("void InitDefaults() {\n");
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
|
||||
string scc_name = ClassName(message_generators_[i]->descriptor_);
|
||||
printer->Print(
|
||||
" ::google::protobuf::internal::InitSCC(&scc_info_$scc_name$.base);\n",
|
||||
"scc_name", scc_name);
|
||||
}
|
||||
printer->Print("}\n\n");
|
||||
|
||||
// Define the code to initialize reflection. This code uses a global
|
||||
// constructor to register reflection data with the runtime pre-main.
|
||||
@ -560,7 +597,7 @@ class FileGenerator::ForwardDeclarations {
|
||||
|
||||
ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
|
||||
ForwardDeclarations*& ns = namespaces_[ns_name];
|
||||
if (ns == NULL) {
|
||||
if (ns == nullptr) {
|
||||
ns = new ForwardDeclarations;
|
||||
}
|
||||
return ns;
|
||||
@ -648,17 +685,12 @@ class FileGenerator::ForwardDeclarations {
|
||||
end = classes_.end();
|
||||
it != end; ++it) {
|
||||
const Descriptor* d = it->second;
|
||||
string extra_class_qualifier;
|
||||
// "class" is to disambiguate in case there is also a function with this
|
||||
// name. There is code out there that does this!
|
||||
printer->Print(
|
||||
"template<> "
|
||||
"$dllexport_decl$"
|
||||
"$class$$classname$* Arena::$func$< $class$$classname$>(Arena*);\n",
|
||||
"classname", QualifiedClassName(d),
|
||||
"func", MessageCreateFunction(d),
|
||||
"class", extra_class_qualifier,
|
||||
"dllexport_decl",
|
||||
"$classname$* Arena::CreateMaybeMessage<$classname$>"
|
||||
"(Arena*);\n",
|
||||
"classname", QualifiedClassName(d), "dllexport_decl",
|
||||
options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ");
|
||||
}
|
||||
printer->Print(
|
||||
@ -758,7 +790,6 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
|
||||
// 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(
|
||||
"void protobuf_AssignDescriptors() {\n"
|
||||
// Make sure the file has found its way into the pool. If a descriptor
|
||||
@ -766,10 +797,9 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
|
||||
// been called yet, so we call it manually. Note that it's fine if
|
||||
// AddDescriptors() is called multiple times.
|
||||
" AddDescriptors();\n"
|
||||
" ::google::protobuf::MessageFactory* factory = $factory$;\n"
|
||||
" AssignDescriptors(\n"
|
||||
" \"$filename$\", schemas, file_default_instances, "
|
||||
"TableStruct::offsets, factory,\n"
|
||||
"TableStruct::offsets,\n"
|
||||
" $metadata$, $enum_descriptors$, $service_descriptors$);\n",
|
||||
"filename", file_->name(), "metadata",
|
||||
!message_generators_.empty() ? "file_level_metadata" : "NULL",
|
||||
@ -778,14 +808,13 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
|
||||
"service_descriptors",
|
||||
HasGenericServices(file_, options_) && file_->service_count() > 0
|
||||
? "file_level_service_descriptors"
|
||||
: "NULL",
|
||||
"factory", message_factory);
|
||||
: "NULL");
|
||||
printer->Print(
|
||||
"}\n"
|
||||
"\n"
|
||||
"void protobuf_AssignDescriptorsOnce() {\n"
|
||||
" static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);\n"
|
||||
" static ::google::protobuf::internal::once_flag once;\n"
|
||||
" ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
"filename", file_->name(), "metadata",
|
||||
@ -795,8 +824,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
|
||||
"service_descriptors",
|
||||
HasGenericServices(file_, options_) && file_->service_count() > 0
|
||||
? "file_level_service_descriptors"
|
||||
: "NULL",
|
||||
"factory", message_factory);
|
||||
: "NULL");
|
||||
|
||||
// Only here because of useless string reference that we don't want in
|
||||
// protobuf_AssignDescriptorsOnce, because that is called from all the
|
||||
@ -891,8 +919,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
|
||||
"}\n"
|
||||
"\n"
|
||||
"void AddDescriptors() {\n"
|
||||
" static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);\n"
|
||||
" static ::google::protobuf::internal::once_flag once;\n"
|
||||
" ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);\n"
|
||||
"}\n");
|
||||
|
||||
printer->Print(
|
||||
@ -907,47 +935,16 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
|
||||
|
||||
void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) {
|
||||
const string scc_name = ClassName(scc->GetRepresentative());
|
||||
// We use static and not anonymous namespace because symbol names are
|
||||
// substantially shorter.
|
||||
printer->Print(
|
||||
"void InitDefaults$scc_name$Impl() {\n"
|
||||
"static void InitDefaults$scc_name$() {\n"
|
||||
" GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n"
|
||||
"#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n"
|
||||
" ::google::protobuf::internal::InitProtobufDefaultsForceUnique();\n"
|
||||
"#else\n"
|
||||
" ::google::protobuf::internal::InitProtobufDefaults();\n"
|
||||
"#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n",
|
||||
// Force initialization of primitive values we depend on.
|
||||
, // awkward comma due to macro
|
||||
"scc_name", scc_name);
|
||||
|
||||
printer->Indent();
|
||||
|
||||
// Call the InitDefaults() methods for all of our dependencies, to make
|
||||
// sure they get added first.
|
||||
for (int i = 0; i < scc->children.size(); i++) {
|
||||
const SCC* child_scc = scc->children[i];
|
||||
const FileDescriptor* dependency = child_scc->GetRepresentative()->file();
|
||||
// Print the namespace prefix for the dependency.
|
||||
string file_namespace = FileLevelNamespace(dependency);
|
||||
std::map<string, string> variables;
|
||||
variables["file_namespace"] = file_namespace;
|
||||
variables["scc_name"] = ClassName(child_scc->GetRepresentative(), false);
|
||||
bool using_weak_fields = UsingImplicitWeakFields(file_, options_);
|
||||
if (using_weak_fields) {
|
||||
// We're building for lite with implicit weak fields, so we need to handle
|
||||
// the possibility that this InitDefaults function is not linked into the
|
||||
// binary. Some of these might actually be guaranteed to be non-null since
|
||||
// we might have a strong reference to the dependency (via a required
|
||||
// field, for example), but it's simplest to just assume that any of them
|
||||
// could be null.
|
||||
printer->Print(
|
||||
variables,
|
||||
"if (&$file_namespace$::InitDefaults$scc_name$ != NULL) {\n"
|
||||
" $file_namespace$::InitDefaults$scc_name$();\n"
|
||||
"}\n");
|
||||
} else {
|
||||
printer->Print(variables,
|
||||
"$file_namespace$::InitDefaults$scc_name$();\n");
|
||||
}
|
||||
}
|
||||
|
||||
// First construct all the necessary default instances.
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
@ -982,23 +979,24 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) {
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
printer->Print(
|
||||
"void InitDefaults$scc_name$() {\n"
|
||||
" static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n"
|
||||
" ::google::protobuf::GoogleOnceInit(&once, "
|
||||
"&InitDefaults$scc_name$Impl);\n"
|
||||
"}\n\n",
|
||||
"scc_name", scc_name);
|
||||
"$dllexport_decl$::google::protobuf::internal::SCCInfo<$size$> "
|
||||
"scc_info_$scc_name$ =\n"
|
||||
" {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), "
|
||||
"$size$, InitDefaults$scc_name$}, {",
|
||||
"size", SimpleItoa(scc->children.size()), "scc_name",
|
||||
ClassName(scc->GetRepresentative()), "dllexport_decl",
|
||||
options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
|
||||
for (const SCC* child : scc->children) {
|
||||
auto repr = child->GetRepresentative();
|
||||
printer->Print("\n &$ns$::scc_info_$child$.base,", "ns",
|
||||
FileLevelNamespace(repr), "child", ClassName(repr));
|
||||
}
|
||||
printer->Print("}};\n\n");
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateInitializationCode(io::Printer* printer) {
|
||||
// Messages depend on the existence of a default instance, which has to
|
||||
// initialized properly. The default instances are allocated in the data
|
||||
// segment, but we can't quite allocate the type directly. The destructors
|
||||
// cannot run at program exit as this could lead to segfaults in a threaded
|
||||
// environment. Hence these instances must be inplace constructed at first
|
||||
// use.
|
||||
|
||||
void FileGenerator::GenerateTables(io::Printer* printer) {
|
||||
if (options_.table_driven_parsing) {
|
||||
// TODO(ckennelly): Gate this with the same options flag to enable
|
||||
// table-driven parsing.
|
||||
@ -1105,16 +1103,6 @@ void FileGenerator::GenerateInitializationCode(io::Printer* printer) {
|
||||
"};\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// All functionality that need private access.
|
||||
|
||||
// Now generate the InitDefaults for each SCC.
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (IsSCCRepresentative(message_generators_[i]->descriptor_)) {
|
||||
GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_), printer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
|
||||
@ -1145,8 +1133,8 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
|
||||
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
|
||||
"// source: $filename$\n"
|
||||
"\n"
|
||||
"#ifndef PROTOBUF_$filename_identifier$_INCLUDED\n"
|
||||
"#define PROTOBUF_$filename_identifier$_INCLUDED\n"
|
||||
"#ifndef PROTOBUF_INCLUDED_$filename_identifier$\n"
|
||||
"#define PROTOBUF_INCLUDED_$filename_identifier$\n"
|
||||
"\n"
|
||||
"#include <string>\n",
|
||||
"filename", file_->name(), "filename_identifier", filename_identifier);
|
||||
@ -1156,7 +1144,7 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
|
||||
void FileGenerator::GenerateBottomHeaderGuard(
|
||||
io::Printer* printer, const string& filename_identifier) {
|
||||
printer->Print(
|
||||
"#endif // PROTOBUF_$filename_identifier$_INCLUDED\n",
|
||||
"#endif // PROTOBUF_INCLUDED_$filename_identifier$\n",
|
||||
"filename_identifier", filename_identifier);
|
||||
}
|
||||
|
||||
@ -1193,7 +1181,9 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
|
||||
"#include <google/protobuf/arena.h>\n"
|
||||
"#include <google/protobuf/arenastring.h>\n"
|
||||
"#include <google/protobuf/generated_message_table_driven.h>\n"
|
||||
"#include <google/protobuf/generated_message_util.h>\n");
|
||||
"#include <google/protobuf/generated_message_util.h>\n"
|
||||
"#include <google/protobuf/inlined_string_field.h>\n");
|
||||
|
||||
|
||||
if (HasDescriptorMethods(file_, options_)) {
|
||||
printer->Print(
|
||||
@ -1280,11 +1270,12 @@ void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
|
||||
const bool use_system_include = IsWellKnownMessage(file_->dependency(i));
|
||||
const string& name = file_->dependency(i)->name();
|
||||
bool public_import = (public_import_names.count(name) != 0);
|
||||
string basename = StripProto(name);
|
||||
|
||||
|
||||
printer->Print(
|
||||
"#include $left$$dependency$.pb.h$right$$iwyu$\n",
|
||||
"dependency", StripProto(name),
|
||||
"dependency", basename,
|
||||
"iwyu", (public_import) ? " // IWYU pragma: export" : "",
|
||||
"left", use_system_include ? "<" : "\"",
|
||||
"right", use_system_include ? ">" : "\"");
|
||||
@ -1318,28 +1309,6 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
|
||||
"void $dllexport_decl$AddDescriptors();\n", "dllexport_decl",
|
||||
options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
|
||||
}
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
|
||||
string scc_name = ClassName(message_generators_[i]->descriptor_);
|
||||
// TODO(gerbens) Remove the Impl from header. This is solely because
|
||||
// it currently still needs to be a friend of the protos.
|
||||
printer->Print(
|
||||
"void $dllexport_decl$InitDefaults$scc_name$Impl();\n"
|
||||
"void $dllexport_decl$InitDefaults$scc_name$();\n",
|
||||
"scc_name", scc_name, "dllexport_decl",
|
||||
options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
|
||||
}
|
||||
// TODO(gerbens) This is for proto1 interoperability. Remove when proto1
|
||||
// is gone.
|
||||
printer->Print(
|
||||
"inline void $dllexport_decl$InitDefaults() {\n", "dllexport_decl",
|
||||
options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
|
||||
for (int i = 0; i < message_generators_.size(); i++) {
|
||||
if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
|
||||
string scc_name = ClassName(message_generators_[i]->descriptor_);
|
||||
printer->Print(" InitDefaults$scc_name$();\n", "scc_name", scc_name);
|
||||
}
|
||||
printer->Print("}\n");
|
||||
printer->Print(
|
||||
"} // namespace $file_namespace$\n",
|
||||
"file_namespace", FileLevelNamespace(file_));
|
||||
@ -1416,8 +1385,6 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
|
||||
printer->Print(kThinSeparator);
|
||||
printer->Print("\n");
|
||||
}
|
||||
// Methods of the dependent base class must always be inline in the header.
|
||||
message_generators_[i]->GenerateDependentInlineMethods(printer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -97,7 +94,7 @@ class FileGenerator {
|
||||
void GenerateSourceDefaultInstance(int idx, io::Printer* printer);
|
||||
|
||||
void GenerateInitForSCC(const SCC* scc, io::Printer* printer);
|
||||
void GenerateInitializationCode(io::Printer* printer);
|
||||
void GenerateTables(io::Printer* printer);
|
||||
void GenerateReflectionInitializationCode(io::Printer* printer);
|
||||
|
||||
// For other imports, generates their forward-declarations.
|
||||
@ -176,10 +173,10 @@ class FileGenerator {
|
||||
|
||||
// These members are just for owning (and thus proper deleting).
|
||||
// Nested (enum/extension)_generators are owned by child messages.
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_owner_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ServiceGenerator> >
|
||||
std::unique_ptr<std::unique_ptr<EnumGenerator> []> enum_generators_owner_;
|
||||
std::unique_ptr<std::unique_ptr<ServiceGenerator> []>
|
||||
service_generators_owner_;
|
||||
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> >
|
||||
std::unique_ptr<std::unique_ptr<ExtensionGenerator> []>
|
||||
extension_generators_owner_;
|
||||
|
||||
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
|
||||
|
@ -36,17 +36,15 @@
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#ifndef _SHARED_PTR_H
|
||||
#include <google/protobuf/stubs/shared_ptr.h>
|
||||
#endif
|
||||
#include <utility>
|
||||
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_file.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -66,12 +64,6 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
// -----------------------------------------------------------------
|
||||
// parse generator options
|
||||
|
||||
// TODO(kenton): If we ever have more options, we may want to create a
|
||||
// class that encapsulates them which we can pass down to all the
|
||||
// generator classes. Currently we pass dllexport_decl down to all of
|
||||
// them via the constructors, but we don't want to have to add another
|
||||
// constructor parameter for every option.
|
||||
|
||||
// If the dllexport_decl option is passed to the compiler, we need to write
|
||||
// it in front of every symbol that should be exported if this .proto is
|
||||
// compiled into a Windows DLL. E.g., if the user invokes the protocol
|
||||
@ -127,11 +119,12 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
|
||||
string basename = StripProto(file->name());
|
||||
|
||||
|
||||
FileGenerator file_generator(file, file_options);
|
||||
|
||||
// Generate header(s).
|
||||
if (file_options.proto_h) {
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".proto.h"));
|
||||
GeneratedCodeInfo annotations;
|
||||
io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
|
||||
@ -143,14 +136,14 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
file_generator.GenerateProtoHeader(
|
||||
&printer, file_options.annotate_headers ? info_path : "");
|
||||
if (file_options.annotate_headers) {
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> info_output(
|
||||
generator_context->Open(info_path));
|
||||
annotations.SerializeToZeroCopyStream(info_output.get());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".pb.h"));
|
||||
GeneratedCodeInfo annotations;
|
||||
io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
|
||||
@ -162,7 +155,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
file_generator.GeneratePBHeader(
|
||||
&printer, file_options.annotate_headers ? info_path : "");
|
||||
if (file_options.annotate_headers) {
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> info_output(
|
||||
generator_context->Open(info_path));
|
||||
annotations.SerializeToZeroCopyStream(info_output.get());
|
||||
}
|
||||
@ -172,7 +165,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
if (UsingImplicitWeakFields(file, file_options)) {
|
||||
{
|
||||
// This is the global .cc file, containing enum/services/tables/reflection
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".pb.cc"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
file_generator.GenerateGlobalSource(&printer);
|
||||
@ -191,7 +184,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
}
|
||||
for (int i = 0; i < num_cc_files; i++) {
|
||||
// TODO(gerbens) Agree on naming scheme.
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + "." + SimpleItoa(i) + ".cc"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
if (i < file_generator.NumMessages()) {
|
||||
@ -199,7 +192,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".pb.cc"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
file_generator.GenerateSource(&printer);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/stubs/substitute.h>
|
||||
|
||||
@ -73,7 +74,7 @@ const char* const kKeywordList[] = {
|
||||
"constexpr", "const_cast", "continue", "decltype", "default", "delete", "do",
|
||||
"double", "dynamic_cast", "else", "enum", "explicit", "export", "extern",
|
||||
"false", "float", "for", "friend", "goto", "if", "inline", "int", "long",
|
||||
"mutable", "namespace", "new", "noexcept", "not", "not_eq", "NULL",
|
||||
"mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr",
|
||||
"operator", "or", "or_eq", "private", "protected", "public", "register",
|
||||
"reinterpret_cast", "return", "short", "signed", "sizeof", "static",
|
||||
"static_assert", "static_cast", "struct", "switch", "template", "this",
|
||||
@ -219,24 +220,12 @@ string ReferenceFunctionName(const Descriptor* descriptor) {
|
||||
return QualifiedClassName(descriptor) + "_ReferenceStrong";
|
||||
}
|
||||
|
||||
string DependentBaseClassTemplateName(const Descriptor* descriptor) {
|
||||
return ClassName(descriptor, false) + "_InternalBase";
|
||||
}
|
||||
|
||||
string SuperClassName(const Descriptor* descriptor, const Options& options) {
|
||||
return HasDescriptorMethods(descriptor->file(), options)
|
||||
? "::google::protobuf::Message"
|
||||
: "::google::protobuf::MessageLite";
|
||||
}
|
||||
|
||||
string DependentBaseDownCast() {
|
||||
return "reinterpret_cast<T*>(this)->";
|
||||
}
|
||||
|
||||
string DependentBaseConstDownCast() {
|
||||
return "reinterpret_cast<const T*>(this)->";
|
||||
}
|
||||
|
||||
string FieldName(const FieldDescriptor* field) {
|
||||
string result = field->name();
|
||||
LowerString(&result);
|
||||
@ -294,60 +283,6 @@ string FieldConstantName(const FieldDescriptor *field) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsFieldDependent(const FieldDescriptor* field) {
|
||||
if (field->containing_oneof() != NULL &&
|
||||
field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
|
||||
return true;
|
||||
}
|
||||
if (field->is_map()) {
|
||||
const Descriptor* map_descriptor = field->message_type();
|
||||
for (int i = 0; i < map_descriptor->field_count(); i++) {
|
||||
if (IsFieldDependent(map_descriptor->field(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
return false;
|
||||
}
|
||||
if (field->containing_oneof() != NULL) {
|
||||
// Oneof fields will always be dependent.
|
||||
//
|
||||
// This is a unique case for field codegen. Field generators are
|
||||
// responsible for generating all the field-specific accessor
|
||||
// functions, except for the clear_*() function; instead, field
|
||||
// generators produce inline clearing code.
|
||||
//
|
||||
// For non-oneof fields, the Message class uses the inline clearing
|
||||
// code to define the field's clear_*() function, as well as in the
|
||||
// destructor. For oneof fields, the Message class generates a much
|
||||
// more complicated clear_*() function, which clears only the oneof
|
||||
// member that is set, in addition to clearing methods for each of the
|
||||
// oneof members individually.
|
||||
//
|
||||
// Since oneofs do not have their own generator class, the Message code
|
||||
// generation logic would be significantly complicated in order to
|
||||
// split dependent and non-dependent manipulation logic based on
|
||||
// whether the oneof truly needs to be dependent; so, for oneof fields,
|
||||
// we just assume it (and its constituents) should be manipulated by a
|
||||
// dependent base class function.
|
||||
//
|
||||
// This is less precise than how dependent message-typed fields are
|
||||
// handled, but the cost is limited to only the generated code for the
|
||||
// oneof field, which seems like an acceptable tradeoff.
|
||||
return true;
|
||||
}
|
||||
if (field->file() == field->message_type()->file()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string DependentTypeName(const FieldDescriptor* field) {
|
||||
return "InternalBase_" + field->name() + "_T";
|
||||
}
|
||||
|
||||
string FieldMessageTypeName(const FieldDescriptor* field) {
|
||||
// Note: The Google-internal version of Protocol Buffers uses this function
|
||||
// as a hook point for hacks to support legacy code.
|
||||
@ -748,12 +683,17 @@ bool UsingImplicitWeakFields(const FileDescriptor* file,
|
||||
GetOptimizeFor(file, options) == FileOptions::LITE_RUNTIME;
|
||||
}
|
||||
|
||||
|
||||
bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options) {
|
||||
bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
|
||||
SCCAnalyzer* scc_analyzer) {
|
||||
return UsingImplicitWeakFields(field->file(), options) &&
|
||||
field->type() == FieldDescriptor::TYPE_MESSAGE &&
|
||||
!field->is_required() && !field->is_map() &&
|
||||
field->containing_oneof() == NULL;
|
||||
field->containing_oneof() == NULL &&
|
||||
!IsWellKnownMessage(field->message_type()->file()) &&
|
||||
// We do not support implicit weak fields between messages in the same
|
||||
// strongly-connected component.
|
||||
scc_analyzer->GetSCC(field->containing_type()) !=
|
||||
scc_analyzer->GetSCC(field->message_type());
|
||||
}
|
||||
|
||||
struct CompareDescriptors {
|
||||
@ -920,6 +860,7 @@ void ListAllTypesForServices(const FileDescriptor* fd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
|
@ -38,8 +38,9 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/cpp/cpp_options.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
@ -53,6 +54,7 @@ namespace cpp {
|
||||
extern const char kThickSeparator[];
|
||||
extern const char kThinSeparator[];
|
||||
|
||||
|
||||
// Name space of the proto file. This namespace is such that the string
|
||||
// "<namespace>::some_name" is the correct fully qualified namespace.
|
||||
// This means if the package is empty the namespace is "", and otherwise
|
||||
@ -102,19 +104,9 @@ string DefaultInstanceName(const Descriptor* descriptor);
|
||||
// fields.
|
||||
string ReferenceFunctionName(const Descriptor* descriptor);
|
||||
|
||||
// Name of the CRTP class template (for use with proto_h).
|
||||
// This is a class name, like "ProtoName_InternalBase".
|
||||
string DependentBaseClassTemplateName(const Descriptor* descriptor);
|
||||
|
||||
// Name of the base class: either the dependent base class (for use with
|
||||
// proto_h) or google::protobuf::Message.
|
||||
// Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
|
||||
string SuperClassName(const Descriptor* descriptor, const Options& options);
|
||||
|
||||
// Returns a string that down-casts from the dependent base class to the
|
||||
// derived class.
|
||||
string DependentBaseDownCast();
|
||||
string DependentBaseConstDownCast();
|
||||
|
||||
// Get the (unqualified) name that should be used for this field in C++ code.
|
||||
// The name is coerced to lower-case to emulate proto1 behavior. People
|
||||
// should be using lowercase-with-underscores style for proto field names
|
||||
@ -141,20 +133,6 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) {
|
||||
field->extension_scope() : field->containing_type();
|
||||
}
|
||||
|
||||
// Returns true if the given 'field_descriptor' has a message type that is
|
||||
// a dependency of the file where the field is defined (i.e., the field
|
||||
// type is defined in a different file than the message holding the field).
|
||||
//
|
||||
// This only applies to Message-typed fields. Enum-typed fields may refer
|
||||
// to an enum in a dependency; however, enums are specified and
|
||||
// forward-declared with an enum-base, so the definition is not required to
|
||||
// manipulate the field value.
|
||||
bool IsFieldDependent(const FieldDescriptor* field_descriptor);
|
||||
|
||||
// Returns the name that should be used for forcing dependent lookup from a
|
||||
// dependent base class.
|
||||
string DependentTypeName(const FieldDescriptor* field);
|
||||
|
||||
// Returns the fully-qualified type name field->message_type(). Usually this
|
||||
// is just ClassName(field->message_type(), true);
|
||||
string FieldMessageTypeName(const FieldDescriptor* field);
|
||||
@ -314,6 +292,11 @@ inline string MessageCreateFunction(const Descriptor* d) {
|
||||
return SupportsArenas(d) ? "CreateMessage" : "Create";
|
||||
}
|
||||
|
||||
inline string MakeDefaultName(const FieldDescriptor* field) {
|
||||
return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
|
||||
"_";
|
||||
}
|
||||
|
||||
bool IsAnyMessage(const FileDescriptor* descriptor);
|
||||
bool IsAnyMessage(const Descriptor* descriptor);
|
||||
|
||||
@ -350,13 +333,6 @@ inline std::vector<const Descriptor*> FlattenMessagesInFile(
|
||||
bool HasWeakFields(const Descriptor* desc);
|
||||
bool HasWeakFields(const FileDescriptor* desc);
|
||||
|
||||
// Indicates whether we should use implicit weak fields for this file.
|
||||
bool UsingImplicitWeakFields(const FileDescriptor* file,
|
||||
const Options& options);
|
||||
|
||||
// Indicates whether to treat this field as implicitly weak.
|
||||
bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options);
|
||||
|
||||
// Returns true if the "required" restriction check should be ignored for the
|
||||
// given field.
|
||||
inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
|
||||
@ -462,11 +438,21 @@ class LIBPROTOC_EXPORT SCCAnalyzer {
|
||||
void AddChildren(SCC* scc);
|
||||
};
|
||||
|
||||
void ListAllFields(const Descriptor* d,
|
||||
std::vector<const FieldDescriptor*>* fields);
|
||||
void ListAllFields(const FileDescriptor* d,
|
||||
std::vector<const FieldDescriptor*>* fields);
|
||||
void ListAllTypesForServices(const FileDescriptor* fd,
|
||||
std::vector<const Descriptor*>* types);
|
||||
|
||||
// Indicates whether we should use implicit weak fields for this file.
|
||||
bool UsingImplicitWeakFields(const FileDescriptor* file,
|
||||
const Options& options);
|
||||
|
||||
// Indicates whether to treat this field as implicitly weak.
|
||||
bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
|
||||
SCCAnalyzer* scc_analyzer);
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
|
@ -104,9 +104,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
|
||||
|
||||
MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: FieldGenerator(options),
|
||||
descriptor_(descriptor),
|
||||
dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
|
||||
: FieldGenerator(options), descriptor_(descriptor) {
|
||||
SetMessageVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
@ -202,7 +200,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
|
||||
key = "entry->key()";
|
||||
value = "entry->value()";
|
||||
printer->Print(variables_,
|
||||
"::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n");
|
||||
"::std::unique_ptr<$map_classname$> entry($name$_.NewEntry());\n");
|
||||
printer->Print(variables_,
|
||||
"{\n"
|
||||
" ::std::string data;\n"
|
||||
@ -258,7 +256,7 @@ static void GenerateSerializationLoop(io::Printer* printer,
|
||||
const string& ptr,
|
||||
bool loop_via_iterators) {
|
||||
printer->Print(variables,
|
||||
StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n",
|
||||
StrCat("::std::unique_ptr<$map_classname$> entry;\n",
|
||||
loop_header, " {\n").c_str());
|
||||
printer->Indent();
|
||||
|
||||
@ -365,7 +363,7 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizes(
|
||||
"\n"
|
||||
"if ($deterministic$ &&\n"
|
||||
" this->$name$().size() > 1) {\n"
|
||||
" ::google::protobuf::scoped_array<SortItem> items(\n"
|
||||
" ::std::unique_ptr<SortItem[]> items(\n"
|
||||
" new SortItem[this->$name$().size()]);\n"
|
||||
" typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n"
|
||||
" size_type n = 0;\n"
|
||||
@ -402,7 +400,7 @@ GenerateByteSize(io::Printer* printer) const {
|
||||
"total_size += $tag_size$ *\n"
|
||||
" ::google::protobuf::internal::FromIntSize(this->$name$_size());\n"
|
||||
"{\n"
|
||||
" ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
|
||||
" ::std::unique_ptr<$map_classname$> entry;\n"
|
||||
" for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
|
||||
" it = this->$name$().begin();\n"
|
||||
" it != this->$name$().end(); ++it) {\n");
|
||||
|
@ -66,7 +66,6 @@ class MapFieldGenerator : public FieldGenerator {
|
||||
io::Printer* printer, const std::map<string, string>& variables) const;
|
||||
|
||||
const FieldDescriptor* descriptor_;
|
||||
const bool dependent_field_;
|
||||
std::map<string, string> variables_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user