Annotate remaining field semantics.

PiperOrigin-RevId: 509872256
pull/11954/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 8f89e0d8db
commit f5f5a1faf1
  1. 13
      src/google/protobuf/compiler/cpp/field_generators/enum_field.cc
  2. 7
      src/google/protobuf/compiler/cpp/field_generators/map_field.cc
  3. 6
      src/google/protobuf/compiler/cpp/field_generators/message_field.cc
  4. 72
      src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc
  5. 6
      src/google/protobuf/compiler/cpp/message.cc
  6. 321
      src/google/protobuf/compiler/cpp/metadata_test.cc

@ -51,6 +51,7 @@ namespace protobuf {
namespace compiler {
namespace cpp {
namespace {
using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
using Sub = ::google::protobuf::io::Printer::Sub;
std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts) {
@ -172,7 +173,8 @@ class SingularEnum : public FieldGeneratorBase {
void SingularEnum::GenerateAccessorDeclarations(io::Printer* p) const {
auto v = p->WithVars(
AnnotatedAccessors(field_, {"", "set_", "_internal_", "_internal_set_"}));
AnnotatedAccessors(field_, {"", "_internal_", "_internal_set_"}));
auto vs = p->WithVars(AnnotatedAccessors(field_, {"set_"}, Semantic::kSet));
p->Emit(R"cc(
$DEPRECATED$ $Enum$ $name$() const;
$DEPRECATED$ void $set_name$($Enum$ value);
@ -331,9 +333,12 @@ class RepeatedEnum : public FieldGeneratorBase {
};
void RepeatedEnum::GenerateAccessorDeclarations(io::Printer* p) const {
auto v = p->WithVars(
AnnotatedAccessors(field_, {"", "set_", "add_", "mutable_", "_internal_",
"_internal_add_", "_internal_mutable_"}));
auto v = p->WithVars(AnnotatedAccessors(
field_, {"", "_internal_", "_internal_add_", "_internal_mutable_"}));
auto vs =
p->WithVars(AnnotatedAccessors(field_, {"set_", "add_"}, Semantic::kSet));
auto vm =
p->WithVars(AnnotatedAccessors(field_, {"mutable_"}, Semantic::kAlias));
p->Emit(R"cc(
public:

@ -30,6 +30,7 @@
#include <memory>
#include <string>
#include <tuple>
#include "absl/container/flat_hash_map.h"
#include "absl/log/absl_check.h"
@ -141,10 +142,12 @@ void MapFieldGenerator::GenerateAccessorDeclarations(
" ${1$_internal_mutable_$name$$}$();\n"
"public:\n"
"$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
" ${1$$name$$}$() const;\n"
" ${1$$name$$}$() const;\n",
descriptor_);
format(
"$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
" ${1$mutable_$name$$}$();\n",
descriptor_);
std::make_tuple(descriptor_, GeneratedCodeInfo::Annotation::ALIAS));
}
void MapFieldGenerator::GenerateInlineAccessorDefinitions(

@ -809,9 +809,11 @@ void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
"$type$* ${1$_internal_add_$name$$}$();\n"
"public:\n",
descriptor_);
format("$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n",
descriptor_);
format("$deprecated_attr$$type$* ${1$add_$name$$}$();\n",
std::make_tuple(descriptor_, GeneratedCodeInfo::Annotation::SET));
format(
"$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
"$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
"$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
" ${1$$name$$}$() const;\n",
descriptor_);

@ -56,7 +56,7 @@ namespace {
using ::google::protobuf::internal::WireFormat;
using ::google::protobuf::internal::WireFormatLite;
using Sub = ::google::protobuf::io::Printer::Sub;
using Annotation = ::google::protobuf::GeneratedCodeInfo::Annotation;
using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
// For encodings with fixed sizes, returns that size in bytes.
absl::optional<size_t> FixedSize(FieldDescriptor::Type type) {
@ -193,18 +193,10 @@ class SingularPrimitive final : public FieldGeneratorBase {
};
void SingularPrimitive::GenerateAccessorDeclarations(io::Printer* p) const {
auto v = p->WithVars(
AnnotatedAccessors(field_, {"", "_internal_", "_internal_set_"}));
auto vs = p->WithVars(AnnotatedAccessors(field_, {"set_"}, Semantic::kSet));
p->Emit(
{
Sub("name", p->LookupVar("name")).AnnotatedAs(field_),
Sub("set_name", absl::StrCat("set_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("_internal_name",
absl::StrCat("_internal_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("_internal_set_name",
absl::StrCat("_internal_set_", p->LookupVar("name")))
.AnnotatedAs(field_),
},
R"cc(
$DEPRECATED$ $Type$ $name$() const;
$DEPRECATED$ void $set_name$($Type$ value);
@ -397,41 +389,27 @@ void RepeatedPrimitive::GeneratePrivateMembers(io::Printer* p) const {
}
void RepeatedPrimitive::GenerateAccessorDeclarations(io::Printer* p) const {
p->Emit(
{
Sub("name", p->LookupVar("name")).AnnotatedAs(field_),
Sub("set_name", absl::StrCat("set_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("add_name", absl::StrCat("add_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("mutable_name", absl::StrCat("mutable_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("_internal_name",
absl::StrCat("_internal_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("_internal_add_name",
absl::StrCat("_internal_add_", p->LookupVar("name")))
.AnnotatedAs(field_),
Sub("_internal_mutable_name",
absl::StrCat("_internal_mutable_", p->LookupVar("name")))
.AnnotatedAs(field_),
},
R"cc(
$DEPRECATED$ $Type$ $name$(int index) const;
$DEPRECATED$ void $set_name$(int index, $Type$ value);
$DEPRECATED$ void $add_name$($Type$ value);
$DEPRECATED$ const $pb$::RepeatedField<$Type$>& $name$() const;
$DEPRECATED$ $pb$::RepeatedField<$Type$>* $mutable_name$();
private:
$Type$ $_internal_name$(int index) const;
void $_internal_add_name$($Type$ value);
const $pb$::RepeatedField<$Type$>& $_internal_name$() const;
$pb$::RepeatedField<$Type$>* $_internal_mutable_name$();
public:
)cc");
auto v = p->WithVars(AnnotatedAccessors(
field_, {"", "_internal_", "_internal_add_", "_internal_mutable_"}));
auto vs =
p->WithVars(AnnotatedAccessors(field_, {"set_", "add_"}, Semantic::kSet));
auto va =
p->WithVars(AnnotatedAccessors(field_, {"mutable_"}, Semantic::kAlias));
p->Emit(R"cc(
$DEPRECATED$ $Type$ $name$(int index) const;
$DEPRECATED$ void $set_name$(int index, $Type$ value);
$DEPRECATED$ void $add_name$($Type$ value);
$DEPRECATED$ const $pb$::RepeatedField<$Type$>& $name$() const;
$DEPRECATED$ $pb$::RepeatedField<$Type$>* $mutable_name$();
private:
$Type$ $_internal_name$(int index) const;
void $_internal_add_name$($Type$ value);
const $pb$::RepeatedField<$Type$>& $_internal_name$() const;
$pb$::RepeatedField<$Type$>* $_internal_mutable_name$();
public:
)cc");
}
void RepeatedPrimitive::GenerateInlineAccessorDefinitions(

@ -85,6 +85,7 @@ using ::google::protobuf::internal::WireFormat;
using ::google::protobuf::internal::WireFormatLite;
using ::google::protobuf::internal::cpp::HasHasbit;
using ::google::protobuf::internal::cpp::Utf8CheckMode;
using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
using Sub = ::google::protobuf::io::Printer::Sub;
static constexpr int kNoHasbit = -1;
@ -730,7 +731,10 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* p) {
{"clearer",
[&] {
p->Emit({Sub("clear_name", absl::StrCat("clear_", name))
.AnnotatedAs(field)},
.AnnotatedAs({
field,
Semantic::kSet,
})},
R"cc(
$deprecated_attr $void $clear_name$() $impl$;
)cc");

@ -177,6 +177,270 @@ TEST_F(CppMetadataTest, RangeChecksWork) {
EXPECT_FALSE(atu::GetAnnotationSubstring(test, annotation).has_value());
}
constexpr absl::string_view kEnumFieldTestFile = R"(
syntax = "proto2";
package foo;
enum Enum { VALUE = 0; }
message Message {
optional Enum efield = 1;
repeated Enum refield = 2;
}
)";
TEST_F(CppMetadataTest, AnnotatesEnumSemantics) {
FileDescriptorProto file;
GeneratedCodeInfo info;
std::string pb_h;
atu::AddFile("test.proto", kEnumFieldTestFile);
EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr,
nullptr, nullptr));
EXPECT_EQ("Message", file.message_type(0).name());
std::vector<int> field_path{FileDescriptorProto::kMessageTypeFieldNumber, 0,
DescriptorProto::kFieldFieldNumber, 0};
std::vector<const GeneratedCodeInfo::Annotation*> annotations;
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "efield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_efield" || *substring == "clear_efield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
}
}
field_path.back() = 1;
annotations.clear();
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "refield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_refield" || *substring == "clear_refield" ||
*substring == "add_refield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_refield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
}
constexpr absl::string_view kMapFieldTestFile = R"(
syntax = "proto2";
package foo;
message Message {
map<string, int32> mfield = 1;
}
)";
TEST_F(CppMetadataTest, AnnotatesMapSemantics) {
FileDescriptorProto file;
GeneratedCodeInfo info;
std::string pb_h;
atu::AddFile("test.proto", kMapFieldTestFile);
EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr,
nullptr, nullptr));
EXPECT_EQ("Message", file.message_type(0).name());
std::vector<int> field_path{FileDescriptorProto::kMessageTypeFieldNumber, 0,
DescriptorProto::kFieldFieldNumber, 0};
std::vector<const GeneratedCodeInfo::Annotation*> annotations;
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "clear_mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
}
constexpr absl::string_view kPrimFieldTestFile = R"(
syntax = "proto2";
package foo;
message Message {
optional int32 ifield = 1;
repeated int32 rifield = 2;
}
)";
TEST_F(CppMetadataTest, AnnotatesPrimSemantics) {
FileDescriptorProto file;
GeneratedCodeInfo info;
std::string pb_h;
atu::AddFile("test.proto", kPrimFieldTestFile);
EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr,
nullptr, nullptr));
EXPECT_EQ("Message", file.message_type(0).name());
std::vector<int> field_path{FileDescriptorProto::kMessageTypeFieldNumber, 0,
DescriptorProto::kFieldFieldNumber, 0};
std::vector<const GeneratedCodeInfo::Annotation*> annotations;
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "ifield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_ifield" || *substring == "clear_ifield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
}
}
field_path.back() = 1;
annotations.clear();
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "rifield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_rifield" || *substring == "clear_rifield" ||
*substring == "add_rifield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_rifield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
}
constexpr absl::string_view kCordFieldTestFile = R"(
syntax = "proto2";
package foo;
message Message {
optional string sfield = 1 [ctype = CORD];
repeated string rsfield = 2 [ctype = CORD];
}
)";
TEST_F(CppMetadataTest, AnnotatesCordSemantics) {
FileDescriptorProto file;
GeneratedCodeInfo info;
std::string pb_h;
atu::AddFile("test.proto", kCordFieldTestFile);
EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr,
nullptr, nullptr));
EXPECT_EQ("Message", file.message_type(0).name());
std::vector<int> field_path{FileDescriptorProto::kMessageTypeFieldNumber, 0,
DescriptorProto::kFieldFieldNumber, 0};
std::vector<const GeneratedCodeInfo::Annotation*> annotations;
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_sfield" || *substring == "clear_sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
field_path.back() = 1;
annotations.clear();
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_rsfield" || *substring == "clear_rsfield" ||
*substring == "add_rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
}
constexpr absl::string_view kStringPieceFieldTestFile = R"(
syntax = "proto2";
package foo;
message Message {
optional string sfield = 1 [ctype = STRING_PIECE];
repeated string rsfield = 2 [ctype = STRING_PIECE];
}
)";
TEST_F(CppMetadataTest, AnnotatesStringPieceSemantics) {
FileDescriptorProto file;
GeneratedCodeInfo info;
std::string pb_h;
atu::AddFile("test.proto", kStringPieceFieldTestFile);
EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr,
nullptr, nullptr));
EXPECT_EQ("Message", file.message_type(0).name());
std::vector<int> field_path{FileDescriptorProto::kMessageTypeFieldNumber, 0,
DescriptorProto::kFieldFieldNumber, 0};
std::vector<const GeneratedCodeInfo::Annotation*> annotations;
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_sfield" || *substring == "set_alias_sfield" ||
*substring == "clear_sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
field_path.back() = 1;
annotations.clear();
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_rsfield" ||
*substring == "set_alias_rsfield" ||
*substring == "clear_rsfield" ||
*substring == "add_alias_rsfield" ||
*substring == "add_rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
}
constexpr absl::string_view kStringFieldTestFile = R"(
syntax = "proto2";
package foo;
@ -205,7 +469,7 @@ TEST_F(CppMetadataTest, AnnotatesStringSemantics) {
if (*substring == "sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_sfield") {
} else if (*substring == "set_sfield" || *substring == "clear_sfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_sfield") {
@ -223,7 +487,8 @@ TEST_F(CppMetadataTest, AnnotatesStringSemantics) {
if (*substring == "rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "set_rsfield") {
} else if (*substring == "set_rsfield" || *substring == "clear_rsfield" ||
*substring == "add_rsfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_rsfield") {
@ -265,6 +530,9 @@ TEST_F(CppMetadataTest, AnnotatesMessageSemantics) {
if (*substring == "mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "clear_mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
@ -277,15 +545,60 @@ TEST_F(CppMetadataTest, AnnotatesMessageSemantics) {
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (substring == "rmfield") {
if (*substring == "rmfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (substring == "mutable_rmfield") {
} else if (*substring == "add_rmfield" || *substring == "clear_rmfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
} else if (*substring == "mutable_rmfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
}
}
}
constexpr absl::string_view kLazyMessageFieldTestFile = R"(
syntax = "proto2";
package foo;
message SMessage { }
message Message {
optional SMessage mfield = 1 [lazy=true];
}
)";
TEST_F(CppMetadataTest, AnnotatesLazyMessageSemantics) {
FileDescriptorProto file;
GeneratedCodeInfo info;
std::string pb_h;
atu::AddFile("test.proto", kLazyMessageFieldTestFile);
EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr,
nullptr, nullptr));
EXPECT_EQ("Message", file.message_type(1).name());
std::vector<int> field_path;
field_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber);
field_path.push_back(1);
field_path.push_back(DescriptorProto::kFieldFieldNumber);
field_path.push_back(0);
std::vector<const GeneratedCodeInfo::Annotation*> annotations;
atu::FindAnnotationsOnPath(info, "test.proto", field_path, &annotations);
EXPECT_TRUE(!annotations.empty());
for (const auto* annotation : annotations) {
auto substring = atu::GetAnnotationSubstring(pb_h, *annotation);
ASSERT_TRUE(substring.has_value());
if (*substring == "mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_NONE,
annotation->semantic());
} else if (*substring == "mutable_mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_ALIAS,
annotation->semantic());
} else if (*substring == "set_encoded_mfield" ||
*substring == "clear_mfield") {
EXPECT_EQ(GeneratedCodeInfo_Annotation_Semantic_SET,
annotation->semantic());
}
}
}
} // namespace
} // namespace cpp
} // namespace compiler

Loading…
Cancel
Save