소스 검색

Parse unknown enum values if target is proto3

Vitaly Buka 6 년 전
부모
커밋
8bbabb87a2
2개의 변경된 파일39개의 추가작업 그리고 2개의 파일을 삭제
  1. 6 2
      src/google/protobuf/text_format.cc
  2. 33 0
      src/google/protobuf/text_format_unittest.cc

+ 6 - 2
src/google/protobuf/text_format.cc

@@ -752,6 +752,7 @@ label_skip_parsing:
 
 
       case FieldDescriptor::CPPTYPE_ENUM: {
       case FieldDescriptor::CPPTYPE_ENUM: {
         string value;
         string value;
+        int64 int_value = kint64max;
         const EnumDescriptor* enum_type = field->enum_type();
         const EnumDescriptor* enum_type = field->enum_type();
         const EnumValueDescriptor* enum_value = NULL;
         const EnumValueDescriptor* enum_value = NULL;
 
 
@@ -762,7 +763,6 @@ label_skip_parsing:
 
 
         } else if (LookingAt("-") ||
         } else if (LookingAt("-") ||
                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
-          int64 int_value;
           DO(ConsumeSignedInteger(&int_value, kint32max));
           DO(ConsumeSignedInteger(&int_value, kint32max));
           value = StrCat(int_value);  // for error reporting
           value = StrCat(int_value);  // for error reporting
           enum_value = enum_type->FindValueByNumber(int_value);
           enum_value = enum_type->FindValueByNumber(int_value);
@@ -773,7 +773,11 @@ label_skip_parsing:
         }
         }
 
 
         if (enum_value == NULL) {
         if (enum_value == NULL) {
-          if (!allow_unknown_enum_) {
+          if (int_value != kint64max &&
+              reflection->SupportsUnknownEnumValues()) {
+            SET_FIELD(EnumValue, int_value);
+            return true;
+          } else if (!allow_unknown_enum_) {
             ReportError("Unknown enumeration value of \"" + value  + "\" for "
             ReportError("Unknown enumeration value of \"" + value  + "\" for "
                         "field \"" + field->name() + "\".");
                         "field \"" + field->name() + "\".");
             return false;
             return false;

+ 33 - 0
src/google/protobuf/text_format_unittest.cc

@@ -48,6 +48,7 @@
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/test_util2.h>
 #include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_proto3.pb.h>
 #include <google/protobuf/unittest_mset.pb.h>
 #include <google/protobuf/unittest_mset.pb.h>
 #include <google/protobuf/unittest_mset_wire_format.pb.h>
 #include <google/protobuf/unittest_mset_wire_format.pb.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/tokenizer.h>
@@ -744,6 +745,38 @@ TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
   EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
   EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
 }
 }
 
 
+TEST_F(TextFormatTest, PrintUnknownEnumFieldProto3) {
+  proto3_unittest::TestAllTypes proto;
+
+  proto.add_repeated_nested_enum(
+      static_cast<proto3_unittest::TestAllTypes::NestedEnum>(10));
+  proto.add_repeated_nested_enum(
+      static_cast<proto3_unittest::TestAllTypes::NestedEnum>(-10));
+  proto.add_repeated_nested_enum(
+      static_cast<proto3_unittest::TestAllTypes::NestedEnum>(2147483647));
+  proto.add_repeated_nested_enum(
+      static_cast<proto3_unittest::TestAllTypes::NestedEnum>(-2147483648));
+
+  EXPECT_EQ(
+      "repeated_nested_enum: 10\n"
+      "repeated_nested_enum: -10\n"
+      "repeated_nested_enum: 2147483647\n"
+      "repeated_nested_enum: -2147483648\n",
+      proto.DebugString());
+}
+
+TEST_F(TextFormatTest, ParseUnknownEnumFieldProto3) {
+  proto3_unittest::TestAllTypes proto;
+  string parse_string =
+      "repeated_nested_enum: [10, -10, 2147483647, -2147483648]";
+  EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+  ASSERT_EQ(4, proto.repeated_nested_enum_size());
+  EXPECT_EQ(10, proto.repeated_nested_enum(0));
+  EXPECT_EQ(-10, proto.repeated_nested_enum(1));
+  EXPECT_EQ(2147483647, proto.repeated_nested_enum(2));
+  EXPECT_EQ(-2147483648, proto.repeated_nested_enum(3));
+}
+
 TEST_F(TextFormatTest, ParseStringEscape) {
 TEST_F(TextFormatTest, ParseStringEscape) {
   // Create a parse string with escpaed characters in it.
   // Create a parse string with escpaed characters in it.
   string parse_string = "optional_string: "
   string parse_string = "optional_string: "