Down integrate to GitHub
This commit is contained in:
parent
7f07bcdcfc
commit
76b4b4b331
@ -2031,6 +2031,16 @@ public final class Descriptors {
|
||||
return outputType;
|
||||
}
|
||||
|
||||
/** Get whether or not the inputs are streaming. */
|
||||
public boolean isClientStreaming() {
|
||||
return proto.getClientStreaming();
|
||||
}
|
||||
|
||||
/** Get whether or not the outputs are streaming. */
|
||||
public boolean isServerStreaming() {
|
||||
return proto.getServerStreaming();
|
||||
}
|
||||
|
||||
/** Get the {@code MethodOptions}, defined in {@code descriptor.proto}. */
|
||||
public MethodOptions getOptions() {
|
||||
return proto.getOptions();
|
||||
|
@ -1525,9 +1525,9 @@ public abstract class GeneratedMessageLite<
|
||||
try {
|
||||
// TODO(yilunchong): Try to make input with type CodedInpuStream.ArrayDecoder use
|
||||
// fast path.
|
||||
Protobuf.getInstance().schemaFor(result).mergeFrom(
|
||||
result, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
|
||||
result.makeImmutable();
|
||||
Schema<T> schema = Protobuf.getInstance().schemaFor(result);
|
||||
schema.mergeFrom(result, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
|
||||
schema.makeImmutable(result);
|
||||
} catch (IOException e) {
|
||||
if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
throw (InvalidProtocolBufferException) e.getCause();
|
||||
@ -1549,10 +1549,10 @@ public abstract class GeneratedMessageLite<
|
||||
@SuppressWarnings("unchecked") // Guaranteed by protoc
|
||||
T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
|
||||
try {
|
||||
Protobuf.getInstance().schemaFor(result).mergeFrom(
|
||||
result, input, offset, offset + length,
|
||||
new ArrayDecoders.Registers(extensionRegistry));
|
||||
result.makeImmutable();
|
||||
Schema<T> schema = Protobuf.getInstance().schemaFor(result);
|
||||
schema.mergeFrom(
|
||||
result, input, offset, offset + length, new ArrayDecoders.Registers(extensionRegistry));
|
||||
schema.makeImmutable(result);
|
||||
if (result.memoizedHashCode != 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
import protobuf_unittest.NestedExtension;
|
||||
import protobuf_unittest.NonNestedExtension;
|
||||
import com.google.protobuf.DescriptorProtos.DescriptorProto;
|
||||
@ -321,6 +324,7 @@ public class DescriptorsTest extends TestCase {
|
||||
assertEquals(UnittestProto.BarResponse.getDescriptor(), barMethod.getOutputType());
|
||||
assertEquals(barMethod, service.findMethodByName("Bar"));
|
||||
|
||||
|
||||
assertNull(service.findMethodByName("NoSuchMethod"));
|
||||
|
||||
for (int i = 0; i < service.getMethods().size(); i++) {
|
||||
|
@ -1000,46 +1000,46 @@ public class TextFormatTest extends TestCase {
|
||||
logger.addHandler(logHandler);
|
||||
// Test unknown extension can pass.
|
||||
assertParseSuccessWithUnknownExtensions("[unknown_extension]: 123");
|
||||
assertParseSuccessWithUnknownExtensions("[unknown_extension]: 123\n"
|
||||
+ "[unknown_ext]: inf\n"
|
||||
+ "[unknown]: 1.234");
|
||||
assertParseSuccessWithUnknownExtensions(
|
||||
"[unknown_extension]: 123\n" + "[unknown_ext]: inf\n" + "[unknown]: 1.234");
|
||||
// Test warning messages.
|
||||
assertEquals("Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]",
|
||||
assertEquals(
|
||||
"Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]",
|
||||
logHandler.getStoredLogRecords().get(0).getMessage());
|
||||
assertEquals("Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n"
|
||||
+ "2:2:\tprotobuf_unittest.TestAllTypes.[unknown_ext]\n"
|
||||
+ "3:2:\tprotobuf_unittest.TestAllTypes.[unknown]",
|
||||
assertEquals(
|
||||
"Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n"
|
||||
+ "2:2:\tprotobuf_unittest.TestAllTypes.[unknown_ext]\n"
|
||||
+ "3:2:\tprotobuf_unittest.TestAllTypes.[unknown]",
|
||||
logHandler.getStoredLogRecords().get(1).getMessage());
|
||||
|
||||
// Test unknown field can not pass.
|
||||
assertParseErrorWithUnknownExtensions(
|
||||
"2:1: Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n"
|
||||
+ "2:1:\tprotobuf_unittest.TestAllTypes.unknown_field",
|
||||
"[unknown_extension]: 1\n"
|
||||
+ "unknown_field: 12345");
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n"
|
||||
+ "2:1:\tprotobuf_unittest.TestAllTypes.unknown_field",
|
||||
"[unknown_extension]: 1\n" + "unknown_field: 12345");
|
||||
assertParseErrorWithUnknownExtensions(
|
||||
"3:1: Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension1]\n"
|
||||
+ "2:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension2]\n"
|
||||
+ "3:1:\tprotobuf_unittest.TestAllTypes.unknown_field\n"
|
||||
+ "4:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension3]",
|
||||
+ "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension1]\n"
|
||||
+ "2:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension2]\n"
|
||||
+ "3:1:\tprotobuf_unittest.TestAllTypes.unknown_field\n"
|
||||
+ "4:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension3]",
|
||||
"[unknown_extension1]: 1\n"
|
||||
+ "[unknown_extension2]: 2\n"
|
||||
+ "unknown_field: 12345\n"
|
||||
+ "[unknown_extension3]: 3\n");
|
||||
+ "[unknown_extension2]: 2\n"
|
||||
+ "unknown_field: 12345\n"
|
||||
+ "[unknown_extension3]: 3\n");
|
||||
assertParseErrorWithUnknownExtensions(
|
||||
"1:1: Input contains unknown fields and/or extensions:\n"
|
||||
+ "1:1:\tprotobuf_unittest.TestAllTypes.unknown_field1\n"
|
||||
+ "2:1:\tprotobuf_unittest.TestAllTypes.unknown_field2\n"
|
||||
+ "3:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n"
|
||||
+ "4:1:\tprotobuf_unittest.TestAllTypes.unknown_field3",
|
||||
+ "1:1:\tprotobuf_unittest.TestAllTypes.unknown_field1\n"
|
||||
+ "2:1:\tprotobuf_unittest.TestAllTypes.unknown_field2\n"
|
||||
+ "3:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n"
|
||||
+ "4:1:\tprotobuf_unittest.TestAllTypes.unknown_field3",
|
||||
"unknown_field1: 1\n"
|
||||
+ "unknown_field2: 2\n"
|
||||
+ "[unknown_extension]: 12345\n"
|
||||
+ "unknown_field3: 3\n");
|
||||
+ "unknown_field2: 2\n"
|
||||
+ "[unknown_extension]: 12345\n"
|
||||
+ "unknown_field3: 3\n");
|
||||
}
|
||||
|
||||
// See additional coverage in testOneofOverwriteForbidden and testMapOverwriteForbidden.
|
||||
|
@ -1563,16 +1563,6 @@ public class JsonFormat {
|
||||
throw new InvalidProtocolBufferException(
|
||||
"Field " + field.getFullName() + " has already been set.");
|
||||
}
|
||||
if (field.getContainingOneof() != null
|
||||
&& builder.getOneofFieldDescriptor(field.getContainingOneof()) != null) {
|
||||
FieldDescriptor other = builder.getOneofFieldDescriptor(field.getContainingOneof());
|
||||
throw new InvalidProtocolBufferException(
|
||||
"Cannot set field "
|
||||
+ field.getFullName()
|
||||
+ " because another field "
|
||||
+ other.getFullName()
|
||||
+ " belonging to the same oneof has already been set ");
|
||||
}
|
||||
}
|
||||
if (field.isRepeated() && json instanceof JsonNull) {
|
||||
// We allow "null" as value for all field types and treat it as if the
|
||||
@ -1583,9 +1573,12 @@ public class JsonFormat {
|
||||
mergeMapField(field, json, builder);
|
||||
} else if (field.isRepeated()) {
|
||||
mergeRepeatedField(field, json, builder);
|
||||
} else if (field.getContainingOneof() != null) {
|
||||
mergeOneofField(field, json, builder);
|
||||
} else {
|
||||
Object value = parseFieldValue(field, json, builder);
|
||||
if (value != null) {
|
||||
// A field interpreted as "null" is means it's treated as absent.
|
||||
builder.setField(field, value);
|
||||
}
|
||||
}
|
||||
@ -1620,6 +1613,24 @@ public class JsonFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeOneofField(FieldDescriptor field, JsonElement json, Message.Builder builder)
|
||||
throws InvalidProtocolBufferException {
|
||||
Object value = parseFieldValue(field, json, builder);
|
||||
if (value == null) {
|
||||
// A field interpreted as "null" is means it's treated as absent.
|
||||
return;
|
||||
}
|
||||
if (builder.getOneofFieldDescriptor(field.getContainingOneof()) != null) {
|
||||
throw new InvalidProtocolBufferException(
|
||||
"Cannot set field "
|
||||
+ field.getFullName()
|
||||
+ " because another field "
|
||||
+ builder.getOneofFieldDescriptor(field.getContainingOneof()).getFullName()
|
||||
+ " belonging to the same oneof has already been set ");
|
||||
}
|
||||
builder.setField(field, value);
|
||||
}
|
||||
|
||||
private void mergeRepeatedField(
|
||||
FieldDescriptor field, JsonElement json, Message.Builder builder)
|
||||
throws InvalidProtocolBufferException {
|
||||
|
@ -464,18 +464,18 @@ public class JsonFormatTest extends TestCase {
|
||||
assertEquals(NullValue.NULL_VALUE, message.getOneofNullValue());
|
||||
}
|
||||
|
||||
public void testNullMessageInDuplicateOneof() throws Exception {
|
||||
// Succeeds if null is first.
|
||||
TestOneof.Builder successBuilder = TestOneof.newBuilder();
|
||||
mergeFromJson("{\"oneofNestedMessage\": null, \"oneofInt32\": 1}", successBuilder);
|
||||
public void testNullFirstInDuplicateOneof() throws Exception {
|
||||
TestOneof.Builder builder = TestOneof.newBuilder();
|
||||
mergeFromJson("{\"oneofNestedMessage\": null, \"oneofInt32\": 1}", builder);
|
||||
TestOneof message = builder.build();
|
||||
assertEquals(1, message.getOneofInt32());
|
||||
}
|
||||
|
||||
// Fails if null is last.
|
||||
try {
|
||||
TestOneof.Builder builder = TestOneof.newBuilder();
|
||||
mergeFromJson("{\"oneofInt32\": 1, \"oneofNestedMessage\": null}", builder);
|
||||
fail();
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
}
|
||||
public void testNullLastInDuplicateOneof() throws Exception {
|
||||
TestOneof.Builder builder = TestOneof.newBuilder();
|
||||
mergeFromJson("{\"oneofInt32\": 1, \"oneofNestedMessage\": null}", builder);
|
||||
TestOneof message = builder.build();
|
||||
assertEquals(1, message.getOneofInt32());
|
||||
}
|
||||
|
||||
public void testParserRejectDuplicatedFields() throws Exception {
|
||||
|
@ -32,8 +32,8 @@ goog.provide('jspb.Map');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
|
||||
goog.forwardDeclare('jspb.BinaryReader');
|
||||
goog.forwardDeclare('jspb.BinaryWriter');
|
||||
goog.requireType('jspb.BinaryReader');
|
||||
goog.requireType('jspb.BinaryWriter');
|
||||
|
||||
|
||||
|
||||
|
@ -44,8 +44,6 @@ goog.require('goog.crypt.base64');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.Map');
|
||||
|
||||
// Not needed in compilation units that have no protos with xids.
|
||||
goog.forwardDeclare('xid.String');
|
||||
|
||||
|
||||
|
||||
@ -286,18 +284,6 @@ jspb.Message.prototype.convertedPrimitiveFields_;
|
||||
jspb.Message.prototype.repeatedFields;
|
||||
|
||||
|
||||
/**
|
||||
* The xid of this proto type (The same for all instances of a proto). Provides
|
||||
* a way to identify a proto by stable obfuscated name.
|
||||
* @see {xid}.
|
||||
* Available if {@link jspb.generate_xid} is added as a Message option to
|
||||
* a protocol buffer.
|
||||
* @const {!xid.String|undefined} The xid or undefined if message is
|
||||
* annotated to generate the xid.
|
||||
*/
|
||||
jspb.Message.prototype.messageXid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the JsPb message_id of this proto.
|
||||
|
@ -325,7 +325,7 @@ std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor)
|
||||
} else if (std::isnan(value)) {
|
||||
return "double.NaN";
|
||||
}
|
||||
return SimpleDtoa(value) + "D";
|
||||
return StrCat(value) + "D";
|
||||
}
|
||||
case FieldDescriptor::TYPE_FLOAT: {
|
||||
float value = descriptor->default_value_float();
|
||||
@ -336,7 +336,7 @@ std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor)
|
||||
} else if (std::isnan(value)) {
|
||||
return "float.NaN";
|
||||
}
|
||||
return SimpleFtoa(value) + "F";
|
||||
return StrCat(value) + "F";
|
||||
}
|
||||
case FieldDescriptor::TYPE_INT64:
|
||||
return StrCat(descriptor->default_value_int64()) + "L";
|
||||
|
@ -419,21 +419,18 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
|
||||
|
||||
printer->Print(
|
||||
"static {\n"
|
||||
" $classname$ defaultInstance = new $classname$();\n"
|
||||
" // New instances are implicitly immutable so no need to make\n"
|
||||
" // immutable.\n"
|
||||
" DEFAULT_INSTANCE = new $classname$();\n"
|
||||
" DEFAULT_INSTANCE = defaultInstance;\n"
|
||||
// Register the default instance in a map. This map will be used by
|
||||
// experimental runtime to lookup default instance given a class instance
|
||||
// without using Java reflection.
|
||||
" com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n"
|
||||
" $classname$.class, defaultInstance);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
"classname", descriptor_->name());
|
||||
// Register the default instance in a map. This map will be used by
|
||||
// experimental runtime to lookup default instance given a class instance
|
||||
// without using Java reflection.
|
||||
printer->Print(
|
||||
"static {\n"
|
||||
" com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n"
|
||||
" $classname$.class, DEFAULT_INSTANCE);\n"
|
||||
"}\n",
|
||||
"classname", descriptor_->name());
|
||||
|
||||
printer->Print(
|
||||
"public static $classname$ getDefaultInstance() {\n"
|
||||
|
@ -1689,6 +1689,27 @@ void Generator::FindProvides(const GeneratorOptions& options,
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
void FindProvidesForOneOfEnum(const GeneratorOptions& options,
|
||||
const OneofDescriptor* oneof,
|
||||
std::set<std::string>* provided) {
|
||||
std::string name = GetMessagePath(options, oneof->containing_type()) + "." +
|
||||
JSOneofName(oneof) + "Case";
|
||||
provided->insert(name);
|
||||
}
|
||||
|
||||
void FindProvidesForOneOfEnums(const GeneratorOptions& options,
|
||||
io::Printer* printer, const Descriptor* desc,
|
||||
std::set<std::string>* provided) {
|
||||
if (HasOneofFields(desc)) {
|
||||
for (int i = 0; i < desc->oneof_decl_count(); i++) {
|
||||
if (IgnoreOneof(desc->oneof_decl(i))) {
|
||||
continue;
|
||||
}
|
||||
FindProvidesForOneOfEnum(options, desc->oneof_decl(i), provided);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Generator::FindProvidesForMessage(const GeneratorOptions& options,
|
||||
io::Printer* printer,
|
||||
const Descriptor* desc,
|
||||
@ -1703,11 +1724,13 @@ void Generator::FindProvidesForMessage(const GeneratorOptions& options,
|
||||
for (int i = 0; i < desc->enum_type_count(); i++) {
|
||||
FindProvidesForEnum(options, printer, desc->enum_type(i), provided);
|
||||
}
|
||||
|
||||
FindProvidesForOneOfEnums(options, printer, desc, provided);
|
||||
|
||||
for (int i = 0; i < desc->nested_type_count(); i++) {
|
||||
FindProvidesForMessage(options, printer, desc->nested_type(i), provided);
|
||||
}
|
||||
}
|
||||
|
||||
void Generator::FindProvidesForEnum(const GeneratorOptions& options,
|
||||
io::Printer* printer,
|
||||
const EnumDescriptor* enumdesc,
|
||||
|
@ -367,20 +367,7 @@ bool Generator::Generate(const FileDescriptor* file,
|
||||
|
||||
return !printer.failed();
|
||||
}
|
||||
// BEGIN GOOGLE-INTERNAL
|
||||
// Strip the google3.third_party.py. prefix off of a module name as we
|
||||
// NEVER want that invalid module import path to be generated in google3.
|
||||
// Our sys.path has google3/third_party/py/ in it. All modules from
|
||||
// that tree need to be imported using just their own name.
|
||||
// See http://go/ThirdPartyPython
|
||||
void StripThirdPartyPy(std::string* module_name) {
|
||||
const std::string third_party_py_prefix = "google3.third_party.py.";
|
||||
int len = third_party_py_prefix.length();
|
||||
if (module_name->compare(0, len, third_party_py_prefix, 0, len) == 0) {
|
||||
*module_name = module_name->erase(0, len);
|
||||
}
|
||||
}
|
||||
// END GOOGLE-INTERNAL
|
||||
|
||||
|
||||
// Prints Python imports for all modules imported by |file|.
|
||||
void Generator::PrintImports() const {
|
||||
@ -389,9 +376,6 @@ void Generator::PrintImports() const {
|
||||
|
||||
std::string module_name = ModuleName(filename);
|
||||
std::string module_alias = ModuleAlias(filename);
|
||||
// BEGIN GOOGLE-INTERNAL
|
||||
StripThirdPartyPy(&module_name);
|
||||
// END GOOGLE-INTERNAL
|
||||
if (ContainsPythonKeyword(module_name)) {
|
||||
// If the module path contains a Python keyword, we have to quote the
|
||||
// module name and import it using importlib. Otherwise the usual kind of
|
||||
@ -422,9 +406,6 @@ void Generator::PrintImports() const {
|
||||
// Print public imports.
|
||||
for (int i = 0; i < file_->public_dependency_count(); ++i) {
|
||||
std::string module_name = ModuleName(file_->public_dependency(i)->name());
|
||||
// BEGIN GOOGLE-INTERNAL
|
||||
StripThirdPartyPy(&module_name);
|
||||
// END GOOGLE-INTERNAL
|
||||
printer_->Print("from $module$ import *\n", "module", module_name);
|
||||
}
|
||||
printer_->Print("\n");
|
||||
@ -674,8 +655,8 @@ void Generator::PrintDescriptorKeyAndModuleName(
|
||||
printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
|
||||
kDescriptorKey, "descriptor_name",
|
||||
ModuleLevelServiceDescriptorName(descriptor));
|
||||
printer_->Print("__module__ = '$module_name$'\n", "module_name",
|
||||
ModuleName(file_->name()));
|
||||
std::string module_name = ModuleName(file_->name());
|
||||
printer_->Print("__module__ = '$module_name$'\n", "module_name", module_name);
|
||||
}
|
||||
|
||||
void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
|
||||
@ -864,8 +845,9 @@ void Generator::PrintMessage(const Descriptor& message_descriptor,
|
||||
m["descriptor_key"] = kDescriptorKey;
|
||||
m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
|
||||
printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
|
||||
std::string module_name = ModuleName(file_->name());
|
||||
printer_->Print("'__module__' : '$module_name$'\n", "module_name",
|
||||
ModuleName(file_->name()));
|
||||
module_name);
|
||||
printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
|
||||
"full_name", message_descriptor.full_name());
|
||||
printer_->Print("})\n");
|
||||
|
@ -454,6 +454,12 @@ bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
|
||||
return index_.FindAllExtensionNumbers(extendee_type, output);
|
||||
}
|
||||
|
||||
bool EncodedDescriptorDatabase::FindAllFileNames(
|
||||
std::vector<std::string>* output) {
|
||||
index_.FindAllFileNames(output);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EncodedDescriptorDatabase::MaybeParse(
|
||||
std::pair<const void*, int> encoded_file, FileDescriptorProto* output) {
|
||||
if (encoded_file.first == NULL) return false;
|
||||
|
@ -327,6 +327,7 @@ class PROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
|
||||
FileDescriptorProto* output) override;
|
||||
bool FindAllExtensionNumbers(const std::string& extendee_type,
|
||||
std::vector<int>* output) override;
|
||||
bool FindAllFileNames(std::vector<std::string>* output) override;
|
||||
|
||||
private:
|
||||
SimpleDescriptorDatabase::DescriptorIndex<std::pair<const void*, int> >
|
||||
|
@ -1078,8 +1078,6 @@ class OneofDescriptorTest : public testing::Test {
|
||||
const FieldDescriptor* b_;
|
||||
const FieldDescriptor* c_;
|
||||
const FieldDescriptor* d_;
|
||||
const FieldDescriptor* e_;
|
||||
const FieldDescriptor* f_;
|
||||
};
|
||||
|
||||
TEST_F(OneofDescriptorTest, Normal) {
|
||||
|
@ -93,8 +93,6 @@ void MapFieldBase::SetRepeatedDirty() {
|
||||
state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void* MapFieldBase::MutableRepeatedPtrField() const { return repeated_field_; }
|
||||
|
||||
void MapFieldBase::SyncRepeatedFieldWithMap() const {
|
||||
// acquire here matches with release below to ensure that we can only see a
|
||||
// value of CLEAN after all previous changes have been synced.
|
||||
|
@ -58,12 +58,6 @@ class MapFieldBaseStub : public MapFieldBase {
|
||||
typedef void DestructorSkippable_;
|
||||
MapFieldBaseStub() {}
|
||||
explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {}
|
||||
void SyncRepeatedFieldWithMap() const {
|
||||
MapFieldBase::SyncRepeatedFieldWithMap();
|
||||
}
|
||||
void SyncMapWithRepeatedField() const {
|
||||
MapFieldBase::SyncMapWithRepeatedField();
|
||||
}
|
||||
// Get underlined repeated field without synchronizing map.
|
||||
RepeatedPtrField<Message>* InternalRepeatedField() { return repeated_field_; }
|
||||
bool IsMapClean() {
|
||||
@ -99,8 +93,6 @@ class MapFieldBaseStub : public MapFieldBase {
|
||||
void CopyIterator(MapIterator* this_iterator,
|
||||
const MapIterator& other_iterator) const override {}
|
||||
void IncreaseIterator(MapIterator* map_iter) const override {}
|
||||
void SetDefaultMessageEntry(const Message* message) const {}
|
||||
const Message* GetDefaultMessageEntry() const { return NULL; }
|
||||
};
|
||||
|
||||
class MapFieldBasePrimitiveTest : public ::testing::Test {
|
||||
|
@ -621,10 +621,6 @@ TEST_F(MapImplTest, IteratorConstness) {
|
||||
}
|
||||
|
||||
bool IsForwardIteratorHelper(std::forward_iterator_tag /*tag*/) { return true; }
|
||||
template <typename T>
|
||||
bool IsForwardIteratorHelper(T /*t*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TEST_F(MapImplTest, IteratorCategory) {
|
||||
EXPECT_TRUE(IsForwardIteratorHelper(
|
||||
|
@ -1599,206 +1599,5 @@ void MapReflectionTester::ExpectClearViaReflectionIterator(Message* message) {
|
||||
reflection->MapEnd(message, F("map_int32_foreign_message")));
|
||||
}
|
||||
|
||||
void MapReflectionTester::ExpectMapEntryClearViaReflection(Message* message) {
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
const Message* sub_message;
|
||||
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_int32_int32");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_int32_int32"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_int64_int64");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_int64_int64"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt64(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt64(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_uint32_uint32");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_uint32_uint32"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt32(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_uint64_uint64");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_uint64_uint64"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt64(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt64(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_sint32_sint32");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_sint32_sint32"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_sint64_sint64");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_sint64_sint64"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt64(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt64(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_fixed32_fixed32");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt32(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_fixed64_fixed64");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt64(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetUInt64(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_sfixed32_sfixed32");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_sfixed64_sfixed64");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt64(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt64(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_int32_float");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_int32_float"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetFloat(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_int32_double");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_int32_double"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetDouble(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_bool_bool");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_bool_bool"));
|
||||
EXPECT_EQ(false, sub_message->GetReflection()->GetBool(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(false, sub_message->GetReflection()->GetBool(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_string_string");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_string_string"));
|
||||
EXPECT_EQ("", sub_message->GetReflection()->GetString(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ("", sub_message->GetReflection()->GetString(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_int32_bytes");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_int32_bytes"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ("", sub_message->GetReflection()->GetString(*sub_message,
|
||||
value_descriptor));
|
||||
}
|
||||
{
|
||||
const FieldDescriptor* descriptor = F("map_int32_enum");
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
sub_message = reflection->AddMessage(message, F("map_int32_enum"));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
|
||||
key_descriptor));
|
||||
EXPECT_EQ(0, sub_message->GetReflection()
|
||||
->GetEnum(*sub_message, value_descriptor)
|
||||
->number());
|
||||
}
|
||||
// Map using message as value has been tested in other place. Thus, we don't
|
||||
// test it here.
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
@ -104,7 +104,6 @@ class MapReflectionTester {
|
||||
void ExpectMapFieldsSetViaReflectionIterator(Message* message);
|
||||
void ExpectClearViaReflection(const Message& message);
|
||||
void ExpectClearViaReflectionIterator(Message* message);
|
||||
void ExpectMapEntryClearViaReflection(Message* message);
|
||||
void GetMapValueViaMapReflection(Message* message,
|
||||
const std::string& field_name,
|
||||
const MapKey& map_key, MapValueRef* map_val);
|
||||
|
@ -173,16 +173,6 @@ class ReflectionAccessor {
|
||||
return static_cast<char*>(msg) + CheckedCast(r)->schema_.GetFieldOffset(f);
|
||||
}
|
||||
|
||||
static ExtensionSet* GetExtensionSet(void* msg, const google::protobuf::Reflection* r) {
|
||||
return reinterpret_cast<ExtensionSet*>(
|
||||
static_cast<char*>(msg) +
|
||||
CheckedCast(r)->schema_.GetExtensionSetOffset());
|
||||
}
|
||||
static InternalMetadataWithArena* GetMetadata(void* msg,
|
||||
const google::protobuf::Reflection* r) {
|
||||
return reinterpret_cast<InternalMetadataWithArena*>(
|
||||
static_cast<char*>(msg) + CheckedCast(r)->schema_.GetMetadataOffset());
|
||||
}
|
||||
static void* GetRepeatedEnum(const Reflection* reflection,
|
||||
const FieldDescriptor* field, Message* msg) {
|
||||
return reflection->MutableRawRepeatedField(
|
||||
@ -677,11 +667,6 @@ class GeneratedMessageFactory : public MessageFactory {
|
||||
public:
|
||||
static GeneratedMessageFactory* singleton();
|
||||
|
||||
struct RegistrationData {
|
||||
const Metadata* file_level_metadata;
|
||||
int size;
|
||||
};
|
||||
|
||||
void RegisterFile(const google::protobuf::internal::DescriptorTable* table);
|
||||
void RegisterType(const Descriptor* descriptor, const Message* prototype);
|
||||
|
||||
|
@ -350,7 +350,11 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma push_macro("GetMessage")
|
||||
#undef GetMessage
|
||||
#endif
|
||||
#pragma push_macro("IGNORE")
|
||||
#undef IGNORE
|
||||
#pragma push_macro("IN")
|
||||
#undef IN
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
|
@ -68,6 +68,8 @@
|
||||
// Restore macro that may have been #undef'd in port_def.inc.
|
||||
#ifdef _MSC_VER
|
||||
#pragma pop_macro("GetMessage")
|
||||
#pragma pop_macro("IGNORE")
|
||||
#pragma pop_macro("IN")
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
|
@ -1634,7 +1634,6 @@ TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) {
|
||||
// string
|
||||
// - i.e. *iter has type std::string*.
|
||||
struct StringLessThan {
|
||||
bool operator()(const std::string* z, const std::string& y) { return *z < y; }
|
||||
bool operator()(const std::string* z, const std::string* y) const {
|
||||
return *z < *y;
|
||||
}
|
||||
|
@ -69,9 +69,7 @@ class ReflectionTester {
|
||||
void ExpectClearViaReflection(const Message& message);
|
||||
|
||||
void SetPackedFieldsViaReflection(Message* message);
|
||||
void ModifyPackedFieldsViaReflection(Message* message);
|
||||
void ExpectPackedFieldsSetViaReflection(const Message& message);
|
||||
void ExpectPackedClearViaReflection(const Message& message);
|
||||
|
||||
void RemoveLastRepeatedsViaReflection(Message* message);
|
||||
void ReleaseLastRepeatedsViaReflection(Message* message,
|
||||
@ -1058,26 +1056,6 @@ inline void TestUtil::ReflectionTester::ExpectClearViaReflection(
|
||||
&scratch));
|
||||
}
|
||||
|
||||
inline void TestUtil::ReflectionTester::ExpectPackedClearViaReflection(
|
||||
const Message& message) {
|
||||
const Reflection* reflection = message.GetReflection();
|
||||
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int32")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int64")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint32")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint64")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint32")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint64")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed32")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed64")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed32")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed64")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_float")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_double")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_bool")));
|
||||
EXPECT_EQ(0, reflection->FieldSize(message, F("packed_enum")));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
|
||||
@ -1128,25 +1106,6 @@ inline void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
|
||||
reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525");
|
||||
}
|
||||
|
||||
inline void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection(
|
||||
Message* message) {
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
reflection->SetRepeatedInt32(message, F("packed_int32"), 1, 801);
|
||||
reflection->SetRepeatedInt64(message, F("packed_int64"), 1, 802);
|
||||
reflection->SetRepeatedUInt32(message, F("packed_uint32"), 1, 803);
|
||||
reflection->SetRepeatedUInt64(message, F("packed_uint64"), 1, 804);
|
||||
reflection->SetRepeatedInt32(message, F("packed_sint32"), 1, 805);
|
||||
reflection->SetRepeatedInt64(message, F("packed_sint64"), 1, 806);
|
||||
reflection->SetRepeatedUInt32(message, F("packed_fixed32"), 1, 807);
|
||||
reflection->SetRepeatedUInt64(message, F("packed_fixed64"), 1, 808);
|
||||
reflection->SetRepeatedInt32(message, F("packed_sfixed32"), 1, 809);
|
||||
reflection->SetRepeatedInt64(message, F("packed_sfixed64"), 1, 810);
|
||||
reflection->SetRepeatedFloat(message, F("packed_float"), 1, 811);
|
||||
reflection->SetRepeatedDouble(message, F("packed_double"), 1, 812);
|
||||
reflection->SetRepeatedBool(message, F("packed_bool"), 1, true);
|
||||
reflection->SetRepeatedEnum(message, F("packed_enum"), 1, foreign_foo_);
|
||||
}
|
||||
|
||||
inline void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(
|
||||
Message* message) {
|
||||
const Reflection* reflection = message->GetReflection();
|
||||
|
@ -69,8 +69,6 @@ inline void SetOneof2(UNITTEST::TestOneof2* message);
|
||||
// the add_*() accessors.
|
||||
inline void ModifyRepeatedFields(UNITTEST::TestAllTypes* message);
|
||||
inline void ModifyRepeatedExtensions(UNITTEST::TestAllExtensions* message);
|
||||
inline void ModifyPackedFields(UNITTEST::TestPackedTypes* message);
|
||||
inline void ModifyPackedExtensions(UNITTEST::TestPackedExtensions* message);
|
||||
|
||||
// Check that all fields have the values that they should have after
|
||||
// Set*Fields() is called.
|
||||
@ -90,17 +88,10 @@ inline void ExpectOneofSet2(const UNITTEST::TestOneof2& message);
|
||||
inline void ExpectRepeatedFieldsModified(const UNITTEST::TestAllTypes& message);
|
||||
inline void ExpectRepeatedExtensionsModified(
|
||||
const UNITTEST::TestAllExtensions& message);
|
||||
inline void ExpectPackedFieldsModified(
|
||||
const UNITTEST::TestPackedTypes& message);
|
||||
inline void ExpectPackedExtensionsModified(
|
||||
const UNITTEST::TestPackedExtensions& message);
|
||||
|
||||
// Check that all fields have their default values.
|
||||
inline void ExpectClear(const UNITTEST::TestAllTypes& message);
|
||||
inline void ExpectExtensionsClear(const UNITTEST::TestAllExtensions& message);
|
||||
inline void ExpectPackedClear(const UNITTEST::TestPackedTypes& message);
|
||||
inline void ExpectPackedExtensionsClear(
|
||||
const UNITTEST::TestPackedExtensions& message);
|
||||
inline void ExpectOneofClear(const UNITTEST::TestOneof2& message);
|
||||
|
||||
// Check that all repeated fields have had their last elements removed.
|
||||
@ -853,25 +844,6 @@ inline void TestUtil::SetUnpackedFields(UNITTEST::TestUnpackedTypes* message) {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ModifyPackedFields(UNITTEST::TestPackedTypes* message) {
|
||||
message->set_packed_int32(1, 801);
|
||||
message->set_packed_int64(1, 802);
|
||||
message->set_packed_uint32(1, 803);
|
||||
message->set_packed_uint64(1, 804);
|
||||
message->set_packed_sint32(1, 805);
|
||||
message->set_packed_sint64(1, 806);
|
||||
message->set_packed_fixed32(1, 807);
|
||||
message->set_packed_fixed64(1, 808);
|
||||
message->set_packed_sfixed32(1, 809);
|
||||
message->set_packed_sfixed64(1, 810);
|
||||
message->set_packed_float(1, 811);
|
||||
message->set_packed_double(1, 812);
|
||||
message->set_packed_bool(1, true);
|
||||
message->set_packed_enum(1, UNITTEST::FOREIGN_FOO);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectPackedFieldsSet(
|
||||
const UNITTEST::TestPackedTypes& message) {
|
||||
ASSERT_EQ(2, message.packed_int32_size());
|
||||
@ -970,78 +942,6 @@ inline void TestUtil::ExpectUnpackedFieldsSet(
|
||||
EXPECT_EQ(UNITTEST::FOREIGN_BAZ, message.unpacked_enum(1));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectPackedClear(
|
||||
const UNITTEST::TestPackedTypes& message) {
|
||||
// Packed repeated fields are empty.
|
||||
EXPECT_EQ(0, message.packed_int32_size());
|
||||
EXPECT_EQ(0, message.packed_int64_size());
|
||||
EXPECT_EQ(0, message.packed_uint32_size());
|
||||
EXPECT_EQ(0, message.packed_uint64_size());
|
||||
EXPECT_EQ(0, message.packed_sint32_size());
|
||||
EXPECT_EQ(0, message.packed_sint64_size());
|
||||
EXPECT_EQ(0, message.packed_fixed32_size());
|
||||
EXPECT_EQ(0, message.packed_fixed64_size());
|
||||
EXPECT_EQ(0, message.packed_sfixed32_size());
|
||||
EXPECT_EQ(0, message.packed_sfixed64_size());
|
||||
EXPECT_EQ(0, message.packed_float_size());
|
||||
EXPECT_EQ(0, message.packed_double_size());
|
||||
EXPECT_EQ(0, message.packed_bool_size());
|
||||
EXPECT_EQ(0, message.packed_enum_size());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectPackedFieldsModified(
|
||||
const UNITTEST::TestPackedTypes& message) {
|
||||
// Do the same for packed repeated fields.
|
||||
ASSERT_EQ(2, message.packed_int32_size());
|
||||
ASSERT_EQ(2, message.packed_int64_size());
|
||||
ASSERT_EQ(2, message.packed_uint32_size());
|
||||
ASSERT_EQ(2, message.packed_uint64_size());
|
||||
ASSERT_EQ(2, message.packed_sint32_size());
|
||||
ASSERT_EQ(2, message.packed_sint64_size());
|
||||
ASSERT_EQ(2, message.packed_fixed32_size());
|
||||
ASSERT_EQ(2, message.packed_fixed64_size());
|
||||
ASSERT_EQ(2, message.packed_sfixed32_size());
|
||||
ASSERT_EQ(2, message.packed_sfixed64_size());
|
||||
ASSERT_EQ(2, message.packed_float_size());
|
||||
ASSERT_EQ(2, message.packed_double_size());
|
||||
ASSERT_EQ(2, message.packed_bool_size());
|
||||
ASSERT_EQ(2, message.packed_enum_size());
|
||||
|
||||
EXPECT_EQ(601, message.packed_int32(0));
|
||||
EXPECT_EQ(602, message.packed_int64(0));
|
||||
EXPECT_EQ(603, message.packed_uint32(0));
|
||||
EXPECT_EQ(604, message.packed_uint64(0));
|
||||
EXPECT_EQ(605, message.packed_sint32(0));
|
||||
EXPECT_EQ(606, message.packed_sint64(0));
|
||||
EXPECT_EQ(607, message.packed_fixed32(0));
|
||||
EXPECT_EQ(608, message.packed_fixed64(0));
|
||||
EXPECT_EQ(609, message.packed_sfixed32(0));
|
||||
EXPECT_EQ(610, message.packed_sfixed64(0));
|
||||
EXPECT_EQ(611, message.packed_float(0));
|
||||
EXPECT_EQ(612, message.packed_double(0));
|
||||
EXPECT_TRUE(message.packed_bool(0));
|
||||
EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.packed_enum(0));
|
||||
// Actually verify the second (modified) elements now.
|
||||
EXPECT_EQ(801, message.packed_int32(1));
|
||||
EXPECT_EQ(802, message.packed_int64(1));
|
||||
EXPECT_EQ(803, message.packed_uint32(1));
|
||||
EXPECT_EQ(804, message.packed_uint64(1));
|
||||
EXPECT_EQ(805, message.packed_sint32(1));
|
||||
EXPECT_EQ(806, message.packed_sint64(1));
|
||||
EXPECT_EQ(807, message.packed_fixed32(1));
|
||||
EXPECT_EQ(808, message.packed_fixed64(1));
|
||||
EXPECT_EQ(809, message.packed_sfixed32(1));
|
||||
EXPECT_EQ(810, message.packed_sfixed64(1));
|
||||
EXPECT_EQ(811, message.packed_float(1));
|
||||
EXPECT_EQ(812, message.packed_double(1));
|
||||
EXPECT_TRUE(message.packed_bool(1));
|
||||
EXPECT_EQ(UNITTEST::FOREIGN_FOO, message.packed_enum(1));
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Extensions
|
||||
//
|
||||
@ -1908,27 +1808,6 @@ inline void TestUtil::SetPackedExtensions(
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ModifyPackedExtensions(
|
||||
UNITTEST::TestPackedExtensions* message) {
|
||||
message->SetExtension(UNITTEST::packed_int32_extension, 1, 801);
|
||||
message->SetExtension(UNITTEST::packed_int64_extension, 1, 802);
|
||||
message->SetExtension(UNITTEST::packed_uint32_extension, 1, 803);
|
||||
message->SetExtension(UNITTEST::packed_uint64_extension, 1, 804);
|
||||
message->SetExtension(UNITTEST::packed_sint32_extension, 1, 805);
|
||||
message->SetExtension(UNITTEST::packed_sint64_extension, 1, 806);
|
||||
message->SetExtension(UNITTEST::packed_fixed32_extension, 1, 807);
|
||||
message->SetExtension(UNITTEST::packed_fixed64_extension, 1, 808);
|
||||
message->SetExtension(UNITTEST::packed_sfixed32_extension, 1, 809);
|
||||
message->SetExtension(UNITTEST::packed_sfixed64_extension, 1, 810);
|
||||
message->SetExtension(UNITTEST::packed_float_extension, 1, 811);
|
||||
message->SetExtension(UNITTEST::packed_double_extension, 1, 812);
|
||||
message->SetExtension(UNITTEST::packed_bool_extension, 1, true);
|
||||
message->SetExtension(UNITTEST::packed_enum_extension, 1,
|
||||
UNITTEST::FOREIGN_FOO);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectPackedExtensionsSet(
|
||||
const UNITTEST::TestPackedExtensions& message) {
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_int32_extension));
|
||||
@ -1980,78 +1859,6 @@ inline void TestUtil::ExpectPackedExtensionsSet(
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectPackedExtensionsClear(
|
||||
const UNITTEST::TestPackedExtensions& message) {
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_int32_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_int64_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_uint32_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_uint64_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_sint32_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_sint64_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_fixed32_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_fixed64_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_sfixed32_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_sfixed64_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_float_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_double_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_bool_extension));
|
||||
EXPECT_EQ(0, message.ExtensionSize(UNITTEST::packed_enum_extension));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectPackedExtensionsModified(
|
||||
const UNITTEST::TestPackedExtensions& message) {
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_int32_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_int64_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_uint32_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_uint64_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sint32_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sint64_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_fixed32_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_fixed64_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sfixed32_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sfixed64_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_float_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_double_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_bool_extension));
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_enum_extension));
|
||||
EXPECT_EQ(601, message.GetExtension(UNITTEST::packed_int32_extension, 0));
|
||||
EXPECT_EQ(602, message.GetExtension(UNITTEST::packed_int64_extension, 0));
|
||||
EXPECT_EQ(603, message.GetExtension(UNITTEST::packed_uint32_extension, 0));
|
||||
EXPECT_EQ(604, message.GetExtension(UNITTEST::packed_uint64_extension, 0));
|
||||
EXPECT_EQ(605, message.GetExtension(UNITTEST::packed_sint32_extension, 0));
|
||||
EXPECT_EQ(606, message.GetExtension(UNITTEST::packed_sint64_extension, 0));
|
||||
EXPECT_EQ(607, message.GetExtension(UNITTEST::packed_fixed32_extension, 0));
|
||||
EXPECT_EQ(608, message.GetExtension(UNITTEST::packed_fixed64_extension, 0));
|
||||
EXPECT_EQ(609, message.GetExtension(UNITTEST::packed_sfixed32_extension, 0));
|
||||
EXPECT_EQ(610, message.GetExtension(UNITTEST::packed_sfixed64_extension, 0));
|
||||
EXPECT_EQ(611, message.GetExtension(UNITTEST::packed_float_extension, 0));
|
||||
EXPECT_EQ(612, message.GetExtension(UNITTEST::packed_double_extension, 0));
|
||||
EXPECT_TRUE(message.GetExtension(UNITTEST::packed_bool_extension, 0));
|
||||
EXPECT_EQ(UNITTEST::FOREIGN_BAR,
|
||||
message.GetExtension(UNITTEST::packed_enum_extension, 0));
|
||||
|
||||
// Actually verify the second (modified) elements now.
|
||||
EXPECT_EQ(801, message.GetExtension(UNITTEST::packed_int32_extension, 1));
|
||||
EXPECT_EQ(802, message.GetExtension(UNITTEST::packed_int64_extension, 1));
|
||||
EXPECT_EQ(803, message.GetExtension(UNITTEST::packed_uint32_extension, 1));
|
||||
EXPECT_EQ(804, message.GetExtension(UNITTEST::packed_uint64_extension, 1));
|
||||
EXPECT_EQ(805, message.GetExtension(UNITTEST::packed_sint32_extension, 1));
|
||||
EXPECT_EQ(806, message.GetExtension(UNITTEST::packed_sint64_extension, 1));
|
||||
EXPECT_EQ(807, message.GetExtension(UNITTEST::packed_fixed32_extension, 1));
|
||||
EXPECT_EQ(808, message.GetExtension(UNITTEST::packed_fixed64_extension, 1));
|
||||
EXPECT_EQ(809, message.GetExtension(UNITTEST::packed_sfixed32_extension, 1));
|
||||
EXPECT_EQ(810, message.GetExtension(UNITTEST::packed_sfixed64_extension, 1));
|
||||
EXPECT_EQ(811, message.GetExtension(UNITTEST::packed_float_extension, 1));
|
||||
EXPECT_EQ(812, message.GetExtension(UNITTEST::packed_double_extension, 1));
|
||||
EXPECT_TRUE(message.GetExtension(UNITTEST::packed_bool_extension, 1));
|
||||
EXPECT_EQ(UNITTEST::FOREIGN_FOO,
|
||||
message.GetExtension(UNITTEST::packed_enum_extension, 1));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline void TestUtil::ExpectUnpackedExtensionsSet(
|
||||
const UNITTEST::TestUnpackedExtensions& message) {
|
||||
ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_int32_extension));
|
||||
|
@ -2408,18 +2408,6 @@ void TextFormat::Printer::PrintFieldValue(const Message& message,
|
||||
return Parser().ParseFieldValueFromString(input, field, message);
|
||||
}
|
||||
|
||||
// Prints an integer as hex with a fixed number of digits dependent on the
|
||||
// integer type.
|
||||
template <typename IntType>
|
||||
static std::string PaddedHex(IntType value) {
|
||||
std::string result;
|
||||
result.reserve(sizeof(value) * 2);
|
||||
for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
|
||||
result.push_back(int_to_hex_digit(value >> (i * 4) & 0x0F));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void TextFormat::Printer::PrintUnknownFields(
|
||||
const UnknownFieldSet& unknown_fields, TextGenerator* generator) const {
|
||||
for (int i = 0; i < unknown_fields.field_count(); i++) {
|
||||
|
@ -45,6 +45,7 @@ namespace protobuf {
|
||||
namespace util {
|
||||
namespace converter {
|
||||
|
||||
|
||||
// An ObjectWriter implementation that outputs JSON. This ObjectWriter
|
||||
// supports writing a compact form or a pretty printed form.
|
||||
//
|
||||
|
@ -88,6 +88,7 @@ class PROTOBUF_EXPORT ObjectWriter {
|
||||
// Renders an 64-bit unsigned integer value.
|
||||
virtual ObjectWriter* RenderUint64(StringPiece name, uint64 value) = 0;
|
||||
|
||||
|
||||
// Renders a double value.
|
||||
virtual ObjectWriter* RenderDouble(StringPiece name, double value) = 0;
|
||||
|
||||
|
@ -804,6 +804,7 @@ Status ProtoStreamObjectSource::RenderField(
|
||||
return util::Status();
|
||||
}
|
||||
|
||||
|
||||
Status ProtoStreamObjectSource::RenderNonMessageField(
|
||||
const google::protobuf::Field* field, StringPiece field_name,
|
||||
ObjectWriter* ow) const {
|
||||
|
@ -940,12 +940,23 @@ bool MessageDifferencer::CompareRepeatedField(
|
||||
std::vector<int> match_list1;
|
||||
std::vector<int> match_list2;
|
||||
|
||||
// Try to match indices of the repeated fields. Return false if match fails
|
||||
// and there's no detailed report needed.
|
||||
if (!MatchRepeatedFieldIndices(message1, message2, repeated_field,
|
||||
*parent_fields, &match_list1, &match_list2) &&
|
||||
reporter_ == NULL) {
|
||||
return false;
|
||||
const MapKeyComparator* key_comparator = GetMapKeyComparator(repeated_field);
|
||||
bool smart_list = IsTreatedAsSmartList(repeated_field);
|
||||
bool simple_list = key_comparator == nullptr &&
|
||||
!IsTreatedAsSet(repeated_field) &&
|
||||
!IsTreatedAsSmartSet(repeated_field) && !smart_list;
|
||||
|
||||
// For simple lists, we avoid matching repeated field indices, saving the
|
||||
// memory allocations that would otherwise be needed for match_list1 and
|
||||
// match_list2.
|
||||
if (!simple_list) {
|
||||
// Try to match indices of the repeated fields. Return false if match fails.
|
||||
if (!MatchRepeatedFieldIndices(message1, message2, repeated_field,
|
||||
key_comparator, *parent_fields, &match_list1,
|
||||
&match_list2) &&
|
||||
reporter_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool fieldDifferent = false;
|
||||
@ -956,8 +967,11 @@ bool MessageDifferencer::CompareRepeatedField(
|
||||
// to be done later). Now to check if the paired elements are different.
|
||||
int next_unmatched_index = 0;
|
||||
for (int i = 0; i < count1; i++) {
|
||||
if (match_list1[i] == -1) {
|
||||
if (IsTreatedAsSmartList(repeated_field)) {
|
||||
if (simple_list && i >= count2) {
|
||||
break;
|
||||
}
|
||||
if (!simple_list && match_list1[i] == -1) {
|
||||
if (smart_list) {
|
||||
if (reporter_ == nullptr) return false;
|
||||
specific_field.index = i;
|
||||
parent_fields->push_back(specific_field);
|
||||
@ -969,7 +983,7 @@ bool MessageDifferencer::CompareRepeatedField(
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (IsTreatedAsSmartList(repeated_field)) {
|
||||
if (smart_list) {
|
||||
for (int j = next_unmatched_index; j < match_list1[i]; ++j) {
|
||||
GOOGLE_CHECK_LE(0, j);
|
||||
if (reporter_ == nullptr) return false;
|
||||
@ -984,8 +998,12 @@ bool MessageDifferencer::CompareRepeatedField(
|
||||
}
|
||||
}
|
||||
specific_field.index = i;
|
||||
specific_field.new_index = match_list1[i];
|
||||
next_unmatched_index = match_list1[i] + 1;
|
||||
if (simple_list) {
|
||||
specific_field.new_index = i;
|
||||
} else {
|
||||
specific_field.new_index = match_list1[i];
|
||||
next_unmatched_index = match_list1[i] + 1;
|
||||
}
|
||||
|
||||
const bool result = CompareFieldValueUsingParentFields(
|
||||
message1, message2, repeated_field, i, specific_field.new_index,
|
||||
@ -1015,7 +1033,8 @@ bool MessageDifferencer::CompareRepeatedField(
|
||||
|
||||
// Report any remaining additions or deletions.
|
||||
for (int i = 0; i < count2; ++i) {
|
||||
if (match_list2[i] != -1) continue;
|
||||
if (!simple_list && match_list2[i] != -1) continue;
|
||||
if (simple_list && i < count1) continue;
|
||||
if (!treated_as_subset) {
|
||||
fieldDifferent = true;
|
||||
}
|
||||
@ -1029,7 +1048,8 @@ bool MessageDifferencer::CompareRepeatedField(
|
||||
}
|
||||
|
||||
for (int i = 0; i < count1; ++i) {
|
||||
if (match_list1[i] != -1) continue;
|
||||
if (!simple_list && match_list1[i] != -1) continue;
|
||||
if (simple_list && i < count2) continue;
|
||||
assert(reporter_ != NULL);
|
||||
specific_field.index = i;
|
||||
parent_fields->push_back(specific_field);
|
||||
@ -1553,21 +1573,19 @@ bool MaximumMatcher::FindArgumentPathDFS(int v, std::vector<bool>* visited) {
|
||||
} // namespace
|
||||
|
||||
bool MessageDifferencer::MatchRepeatedFieldIndices(
|
||||
const Message& message1,
|
||||
const Message& message2,
|
||||
const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* repeated_field,
|
||||
const MapKeyComparator* key_comparator,
|
||||
const std::vector<SpecificField>& parent_fields,
|
||||
std::vector<int>* match_list1,
|
||||
std::vector<int>* match_list2) {
|
||||
std::vector<int>* match_list1, std::vector<int>* match_list2) {
|
||||
const int count1 =
|
||||
message1.GetReflection()->FieldSize(message1, repeated_field);
|
||||
const int count2 =
|
||||
message2.GetReflection()->FieldSize(message2, repeated_field);
|
||||
const MapKeyComparator* key_comparator = GetMapKeyComparator(repeated_field);
|
||||
const bool is_treated_as_smart_set = IsTreatedAsSmartSet(repeated_field);
|
||||
|
||||
match_list1->assign(count1, -1);
|
||||
match_list2->assign(count2, -1);
|
||||
|
||||
// Ensure that we don't report differences during the matching process. Since
|
||||
// field comparators could potentially use this message differencer object to
|
||||
// perform further comparisons, turn off reporting here and re-enable it
|
||||
@ -1576,114 +1594,100 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
|
||||
reporter_ = NULL;
|
||||
NumDiffsReporter num_diffs_reporter;
|
||||
std::vector<int32> num_diffs_list1;
|
||||
if (IsTreatedAsSmartSet(repeated_field)) {
|
||||
if (is_treated_as_smart_set) {
|
||||
num_diffs_list1.assign(count1, kint32max);
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
// Find potential match if this is a special repeated field.
|
||||
if (key_comparator != nullptr || IsTreatedAsSet(repeated_field) ||
|
||||
IsTreatedAsSmartSet(repeated_field) ||
|
||||
IsTreatedAsSmartList(repeated_field)) {
|
||||
if (scope_ == PARTIAL) {
|
||||
// When partial matching is enabled, Compare(a, b) && Compare(a, c)
|
||||
// doesn't necessarily imply Compare(b, c). Therefore a naive greedy
|
||||
// algorithm will fail to find a maximum matching.
|
||||
// Here we use the augmenting path algorithm.
|
||||
MaximumMatcher::NodeMatchCallback* callback = ::google::protobuf::NewPermanentCallback(
|
||||
this, &MessageDifferencer::IsMatch, repeated_field, key_comparator,
|
||||
&message1, &message2, parent_fields, nullptr);
|
||||
MaximumMatcher matcher(count1, count2, callback, match_list1,
|
||||
match_list2);
|
||||
// If diff info is not needed, we should end the matching process as
|
||||
// soon as possible if not all items can be matched.
|
||||
bool early_return = (reporter == NULL);
|
||||
int match_count = matcher.FindMaximumMatch(early_return);
|
||||
if (match_count != count1 && reporter == NULL) return false;
|
||||
success = success && (match_count == count1);
|
||||
} else {
|
||||
int start_offset = 0;
|
||||
const bool is_treated_as_smart_set = IsTreatedAsSmartSet(repeated_field);
|
||||
// If the two repeated fields are treated as sets, optimize for the case
|
||||
// where both start with same items stored in the same order.
|
||||
if (IsTreatedAsSet(repeated_field) || is_treated_as_smart_set ||
|
||||
IsTreatedAsSmartList(repeated_field)) {
|
||||
start_offset = std::min(count1, count2);
|
||||
for (int i = 0; i < count1 && i < count2; i++) {
|
||||
if (IsMatch(repeated_field, key_comparator, &message1, &message2,
|
||||
parent_fields, nullptr, i, i)) {
|
||||
match_list1->at(i) = i;
|
||||
match_list2->at(i) = i;
|
||||
} else {
|
||||
start_offset = i;
|
||||
if (scope_ == PARTIAL) {
|
||||
// When partial matching is enabled, Compare(a, b) && Compare(a, c)
|
||||
// doesn't necessarily imply Compare(b, c). Therefore a naive greedy
|
||||
// algorithm will fail to find a maximum matching.
|
||||
// Here we use the augmenting path algorithm.
|
||||
MaximumMatcher::NodeMatchCallback* callback = ::google::protobuf::NewPermanentCallback(
|
||||
this, &MessageDifferencer::IsMatch, repeated_field, key_comparator,
|
||||
&message1, &message2, parent_fields, nullptr);
|
||||
MaximumMatcher matcher(count1, count2, callback, match_list1, match_list2);
|
||||
// If diff info is not needed, we should end the matching process as
|
||||
// soon as possible if not all items can be matched.
|
||||
bool early_return = (reporter == nullptr);
|
||||
int match_count = matcher.FindMaximumMatch(early_return);
|
||||
if (match_count != count1 && early_return) return false;
|
||||
success = success && (match_count == count1);
|
||||
} else {
|
||||
int start_offset = 0;
|
||||
// If the two repeated fields are treated as sets, optimize for the case
|
||||
// where both start with same items stored in the same order.
|
||||
if (IsTreatedAsSet(repeated_field) || is_treated_as_smart_set ||
|
||||
IsTreatedAsSmartList(repeated_field)) {
|
||||
start_offset = std::min(count1, count2);
|
||||
for (int i = 0; i < count1 && i < count2; i++) {
|
||||
if (IsMatch(repeated_field, key_comparator, &message1, &message2,
|
||||
parent_fields, nullptr, i, i)) {
|
||||
match_list1->at(i) = i;
|
||||
match_list2->at(i) = i;
|
||||
} else {
|
||||
start_offset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = start_offset; i < count1; ++i) {
|
||||
// Indicates any matched elements for this repeated field.
|
||||
bool match = false;
|
||||
int matched_j = -1;
|
||||
|
||||
for (int j = start_offset; j < count2; j++) {
|
||||
if (match_list2->at(j) != -1) {
|
||||
if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_treated_as_smart_set) {
|
||||
num_diffs_reporter.Reset();
|
||||
match = IsMatch(repeated_field, key_comparator, &message1, &message2,
|
||||
parent_fields, &num_diffs_reporter, i, j);
|
||||
} else {
|
||||
match = IsMatch(repeated_field, key_comparator, &message1, &message2,
|
||||
parent_fields, nullptr, i, j);
|
||||
}
|
||||
|
||||
if (is_treated_as_smart_set) {
|
||||
if (match) {
|
||||
num_diffs_list1[i] = 0;
|
||||
} else if (repeated_field->cpp_type() ==
|
||||
FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
// Replace with the one with fewer diffs.
|
||||
const int32 num_diffs = num_diffs_reporter.GetNumDiffs();
|
||||
if (num_diffs < num_diffs_list1[i]) {
|
||||
num_diffs_list1[i] = num_diffs;
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
matched_j = j;
|
||||
if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = start_offset; i < count1; ++i) {
|
||||
// Indicates any matched elements for this repeated field.
|
||||
bool match = false;
|
||||
int matched_j = -1;
|
||||
|
||||
for (int j = start_offset; j < count2; j++) {
|
||||
if (match_list2->at(j) != -1) {
|
||||
if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_treated_as_smart_set) {
|
||||
num_diffs_reporter.Reset();
|
||||
match =
|
||||
IsMatch(repeated_field, key_comparator, &message1, &message2,
|
||||
parent_fields, &num_diffs_reporter, i, j);
|
||||
} else {
|
||||
match = IsMatch(repeated_field, key_comparator, &message1,
|
||||
&message2, parent_fields, nullptr, i, j);
|
||||
}
|
||||
|
||||
if (is_treated_as_smart_set) {
|
||||
if (match) {
|
||||
num_diffs_list1[i] = 0;
|
||||
} else if (repeated_field->cpp_type() ==
|
||||
FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
// Replace with the one with fewer diffs.
|
||||
const int32 num_diffs = num_diffs_reporter.GetNumDiffs();
|
||||
if (num_diffs < num_diffs_list1[i]) {
|
||||
num_diffs_list1[i] = num_diffs;
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
matched_j = j;
|
||||
if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
match = (matched_j != -1);
|
||||
if (match) {
|
||||
if (is_treated_as_smart_set && match_list2->at(matched_j) != -1) {
|
||||
// This is to revert the previously matched index in list2.
|
||||
match_list1->at(match_list2->at(matched_j)) = -1;
|
||||
match = false;
|
||||
}
|
||||
|
||||
match = (matched_j != -1);
|
||||
if (match) {
|
||||
if (is_treated_as_smart_set &&
|
||||
match_list2->at(matched_j) != -1) {
|
||||
// This is to revert the previously matched index in list2.
|
||||
match_list1->at(match_list2->at(matched_j)) = -1;
|
||||
match = false;
|
||||
}
|
||||
match_list1->at(i) = matched_j;
|
||||
match_list2->at(matched_j) = i;
|
||||
}
|
||||
if (!match && reporter == NULL) return false;
|
||||
success = success && match;
|
||||
match_list1->at(i) = matched_j;
|
||||
match_list2->at(matched_j) = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If this field should be treated as list, just label the match_list.
|
||||
for (int i = 0; i < count1 && i < count2; i++) {
|
||||
match_list1->at(i) = i;
|
||||
match_list2->at(i) = i;
|
||||
if (!match && reporter == nullptr) return false;
|
||||
success = success && match;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -824,12 +824,14 @@ class PROTOBUF_EXPORT MessageDifferencer {
|
||||
// match. Clears output vectors and sets their values to indices of paired
|
||||
// messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1
|
||||
// and match_list2[1] == 0. The unmatched indices are indicated by -1.
|
||||
// Assumes the repeated field is not treated as a simple list.
|
||||
// This method returns false if the match failed. However, it doesn't mean
|
||||
// that the comparison succeeds when this method returns true (you need to
|
||||
// double-check in this case).
|
||||
bool MatchRepeatedFieldIndices(
|
||||
const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* repeated_field,
|
||||
const MapKeyComparator* key_comparator,
|
||||
const std::vector<SpecificField>& parent_fields,
|
||||
std::vector<int>* match_list1, std::vector<int>* match_list2);
|
||||
|
||||
|
@ -38,6 +38,8 @@ syntax = "proto2";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
option optimize_for = SPEED;
|
||||
|
||||
message TestField {
|
||||
@ -69,6 +71,8 @@ message TestDiffMessage {
|
||||
repeated int32 rv = 11; // Test for combinations
|
||||
repeated string rw = 10; // Test for combinations
|
||||
repeated TestField rm = 12 [deprecated = true]; // Test for combinations
|
||||
repeated google.protobuf.Any rany =
|
||||
16; // Test for repeated Any type resolution
|
||||
|
||||
extensions 100 to 199;
|
||||
}
|
||||
|
@ -290,25 +290,6 @@ void CodedOutputStreamFieldSkipper::SkipUnknownEnum(int field_number,
|
||||
unknown_fields_->WriteVarint64(value);
|
||||
}
|
||||
|
||||
bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
|
||||
bool (*is_valid)(int),
|
||||
RepeatedField<int>* values) {
|
||||
uint32 length;
|
||||
if (!input->ReadVarint32(&length)) return false;
|
||||
io::CodedInputStream::Limit limit = input->PushLimit(length);
|
||||
while (input->BytesUntilLimit() > 0) {
|
||||
int value;
|
||||
if (!ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(input, &value)) {
|
||||
return false;
|
||||
}
|
||||
if (is_valid == NULL || is_valid(value)) {
|
||||
values->Add(value);
|
||||
}
|
||||
}
|
||||
input->PopLimit(limit);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WireFormatLite::ReadPackedEnumPreserveUnknowns(
|
||||
io::CodedInputStream* input, int field_number, bool (*is_valid)(int),
|
||||
io::CodedOutputStream* unknown_fields_stream, RepeatedField<int>* values) {
|
||||
|
Loading…
Reference in New Issue
Block a user