Down-integrate from internal code base.

pull/111/head
Feng Xiao 10 years ago
parent 90f2f50233
commit c25d9feb4d
  1. 42
      src/google/protobuf/compiler/cpp/cpp_message.cc
  2. 9
      src/google/protobuf/compiler/plugin.pb.cc
  3. 63
      src/google/protobuf/descriptor.pb.cc
  4. 33
      src/google/protobuf/dynamic_message.cc
  5. 47
      src/google/protobuf/dynamic_message_unittest.cc
  6. 34
      src/google/protobuf/generated_message_reflection.cc
  7. 17
      src/google/protobuf/generated_message_reflection.h
  8. 11
      src/google/protobuf/no_field_presence_test.cc

@ -561,7 +561,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
} else { } else {
printer->Print(vars, printer->Print(vars,
"inline bool $classname$::has_$name$() const {\n" "inline bool $classname$::has_$name$() const {\n"
" return $name$_ != NULL;\n" " return !_is_default_instance_ && $name$_ != NULL;\n"
"}\n"); "}\n");
} }
} }
@ -1051,6 +1051,22 @@ GenerateClassDefinition(io::Printer* printer) {
printer->Print(cached_size_decl.c_str()); printer->Print(cached_size_decl.c_str());
need_to_emit_cached_size = false; need_to_emit_cached_size = false;
} }
} else {
// Without field presence, we need another way to disambiguate the default
// instance, because the default instance's submessage fields (if any) store
// pointers to the default instances of the submessages even when they
// aren't present. Alternatives to this approach might be to (i) use a
// tagged pointer on all message fields, setting a tag bit for "not really
// present, just default instance"; or (ii) comparing |this| against the
// return value from GeneratedMessageFactory::GetPrototype() in all
// has_$field$() calls. However, both of these options are much more
// expensive (in code size and CPU overhead) than just checking a field in
// the message. Long-term, the best solution would be to rearchitect the
// default instance design not to store pointers to submessage default
// instances, and have reflection get those some other way; but that change
// would have too much impact on proto2.
printer->Print(
"bool _is_default_instance_;\n");
} }
// Field members: // Field members:
@ -1323,11 +1339,21 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
if (UseUnknownFieldSet(descriptor_->file())) { if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print(vars, printer->Print(vars,
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
"$classname$, _internal_metadata_));\n"); "$classname$, _internal_metadata_),\n");
} else {
printer->Print(vars,
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
"$classname$, _arena_),\n");
}
// is_default_instance_ offset.
if (HasFieldPresence(descriptor_->file())) {
printer->Print(vars,
" -1);\n");
} else { } else {
printer->Print(vars, printer->Print(vars,
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
"$classname$, _arena_));\n"); "$classname$, _is_default_instance_));\n");
} }
// Handle nested types. // Handle nested types.
@ -1612,6 +1638,11 @@ GenerateSharedConstructorCode(io::Printer* printer) {
"classname", classname_); "classname", classname_);
printer->Indent(); printer->Indent();
if (!HasFieldPresence(descriptor_->file())) {
printer->Print(
" _is_default_instance_ = false;\n");
}
printer->Print(StrCat( printer->Print(StrCat(
uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "", uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
"_cached_size_ = 0;\n").c_str()); "_cached_size_ = 0;\n").c_str());
@ -1809,6 +1840,11 @@ GenerateStructors(io::Printer* printer) {
"void $classname$::InitAsDefaultInstance() {\n", "void $classname$::InitAsDefaultInstance() {\n",
"classname", classname_); "classname", classname_);
if (!HasFieldPresence(descriptor_->file())) {
printer->Print(
" _is_default_instance_ = true;\n");
}
// The default instance needs all of its embedded message pointers // The default instance needs all of its embedded message pointers
// cross-linked to other default instances. We can't do this initialization // cross-linked to other default instances. We can't do this initialization
// in the constructor because some other default instances may not have been // in the constructor because some other default instances may not have been

@ -56,7 +56,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
-1, -1,
-1, -1,
sizeof(CodeGeneratorRequest), sizeof(CodeGeneratorRequest),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_),
-1);
CodeGeneratorResponse_descriptor_ = file->message_type(1); CodeGeneratorResponse_descriptor_ = file->message_type(1);
static const int CodeGeneratorResponse_offsets_[2] = { static const int CodeGeneratorResponse_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_),
@ -71,7 +72,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
-1, -1,
-1, -1,
sizeof(CodeGeneratorResponse), sizeof(CodeGeneratorResponse),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _internal_metadata_),
-1);
CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0); CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0);
static const int CodeGeneratorResponse_File_offsets_[3] = { static const int CodeGeneratorResponse_File_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_),
@ -87,7 +89,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
-1, -1,
-1, -1,
sizeof(CodeGeneratorResponse_File), sizeof(CodeGeneratorResponse_File),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_),
-1);
} }
namespace { namespace {

@ -111,7 +111,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(FileDescriptorSet), sizeof(FileDescriptorSet),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _internal_metadata_),
-1);
FileDescriptorProto_descriptor_ = file->message_type(1); FileDescriptorProto_descriptor_ = file->message_type(1);
static const int FileDescriptorProto_offsets_[12] = { static const int FileDescriptorProto_offsets_[12] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
@ -136,7 +137,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(FileDescriptorProto), sizeof(FileDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _internal_metadata_),
-1);
DescriptorProto_descriptor_ = file->message_type(2); DescriptorProto_descriptor_ = file->message_type(2);
static const int DescriptorProto_offsets_[8] = { static const int DescriptorProto_offsets_[8] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
@ -157,7 +159,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(DescriptorProto), sizeof(DescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _internal_metadata_),
-1);
DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0); DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
static const int DescriptorProto_ExtensionRange_offsets_[2] = { static const int DescriptorProto_ExtensionRange_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_),
@ -172,7 +175,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(DescriptorProto_ExtensionRange), sizeof(DescriptorProto_ExtensionRange),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _internal_metadata_),
-1);
FieldDescriptorProto_descriptor_ = file->message_type(3); FieldDescriptorProto_descriptor_ = file->message_type(3);
static const int FieldDescriptorProto_offsets_[9] = { static const int FieldDescriptorProto_offsets_[9] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
@ -194,7 +198,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(FieldDescriptorProto), sizeof(FieldDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _internal_metadata_),
-1);
FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0); FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1); FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
OneofDescriptorProto_descriptor_ = file->message_type(4); OneofDescriptorProto_descriptor_ = file->message_type(4);
@ -210,7 +215,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(OneofDescriptorProto), sizeof(OneofDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _internal_metadata_),
-1);
EnumDescriptorProto_descriptor_ = file->message_type(5); EnumDescriptorProto_descriptor_ = file->message_type(5);
static const int EnumDescriptorProto_offsets_[3] = { static const int EnumDescriptorProto_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
@ -226,7 +232,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(EnumDescriptorProto), sizeof(EnumDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _internal_metadata_),
-1);
EnumValueDescriptorProto_descriptor_ = file->message_type(6); EnumValueDescriptorProto_descriptor_ = file->message_type(6);
static const int EnumValueDescriptorProto_offsets_[3] = { static const int EnumValueDescriptorProto_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
@ -242,7 +249,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(EnumValueDescriptorProto), sizeof(EnumValueDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _internal_metadata_),
-1);
ServiceDescriptorProto_descriptor_ = file->message_type(7); ServiceDescriptorProto_descriptor_ = file->message_type(7);
static const int ServiceDescriptorProto_offsets_[3] = { static const int ServiceDescriptorProto_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
@ -258,7 +266,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(ServiceDescriptorProto), sizeof(ServiceDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _internal_metadata_),
-1);
MethodDescriptorProto_descriptor_ = file->message_type(8); MethodDescriptorProto_descriptor_ = file->message_type(8);
static const int MethodDescriptorProto_offsets_[6] = { static const int MethodDescriptorProto_offsets_[6] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
@ -277,7 +286,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(MethodDescriptorProto), sizeof(MethodDescriptorProto),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
-1);
FileOptions_descriptor_ = file->message_type(9); FileOptions_descriptor_ = file->message_type(9);
static const int FileOptions_offsets_[13] = { static const int FileOptions_offsets_[13] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
@ -303,7 +313,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_),
sizeof(FileOptions), sizeof(FileOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _internal_metadata_),
-1);
FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0); FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
MessageOptions_descriptor_ = file->message_type(10); MessageOptions_descriptor_ = file->message_type(10);
static const int MessageOptions_offsets_[5] = { static const int MessageOptions_offsets_[5] = {
@ -322,7 +333,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_),
sizeof(MessageOptions), sizeof(MessageOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_),
-1);
FieldOptions_descriptor_ = file->message_type(11); FieldOptions_descriptor_ = file->message_type(11);
static const int FieldOptions_offsets_[6] = { static const int FieldOptions_offsets_[6] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
@ -341,7 +353,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_),
sizeof(FieldOptions), sizeof(FieldOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _internal_metadata_),
-1);
FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0); FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
EnumOptions_descriptor_ = file->message_type(12); EnumOptions_descriptor_ = file->message_type(12);
static const int EnumOptions_offsets_[3] = { static const int EnumOptions_offsets_[3] = {
@ -358,7 +371,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_),
sizeof(EnumOptions), sizeof(EnumOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _internal_metadata_),
-1);
EnumValueOptions_descriptor_ = file->message_type(13); EnumValueOptions_descriptor_ = file->message_type(13);
static const int EnumValueOptions_offsets_[2] = { static const int EnumValueOptions_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_),
@ -373,7 +387,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_),
sizeof(EnumValueOptions), sizeof(EnumValueOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _internal_metadata_),
-1);
ServiceOptions_descriptor_ = file->message_type(14); ServiceOptions_descriptor_ = file->message_type(14);
static const int ServiceOptions_offsets_[2] = { static const int ServiceOptions_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_),
@ -388,7 +403,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_),
sizeof(ServiceOptions), sizeof(ServiceOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _internal_metadata_),
-1);
MethodOptions_descriptor_ = file->message_type(15); MethodOptions_descriptor_ = file->message_type(15);
static const int MethodOptions_offsets_[2] = { static const int MethodOptions_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_),
@ -403,7 +419,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_),
sizeof(MethodOptions), sizeof(MethodOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _internal_metadata_),
-1);
UninterpretedOption_descriptor_ = file->message_type(16); UninterpretedOption_descriptor_ = file->message_type(16);
static const int UninterpretedOption_offsets_[7] = { static const int UninterpretedOption_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
@ -423,7 +440,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(UninterpretedOption), sizeof(UninterpretedOption),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _internal_metadata_),
-1);
UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0); UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0);
static const int UninterpretedOption_NamePart_offsets_[2] = { static const int UninterpretedOption_NamePart_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_),
@ -438,7 +456,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(UninterpretedOption_NamePart), sizeof(UninterpretedOption_NamePart),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _internal_metadata_),
-1);
SourceCodeInfo_descriptor_ = file->message_type(17); SourceCodeInfo_descriptor_ = file->message_type(17);
static const int SourceCodeInfo_offsets_[1] = { static const int SourceCodeInfo_offsets_[1] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
@ -452,7 +471,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(SourceCodeInfo), sizeof(SourceCodeInfo),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _internal_metadata_),
-1);
SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0); SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
static const int SourceCodeInfo_Location_offsets_[4] = { static const int SourceCodeInfo_Location_offsets_[4] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
@ -469,7 +489,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1, -1,
-1, -1,
sizeof(SourceCodeInfo_Location), sizeof(SourceCodeInfo_Location),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _internal_metadata_)); GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _internal_metadata_),
-1);
} }
namespace { namespace {

@ -218,6 +218,7 @@ class DynamicMessage : public Message {
int oneof_case_offset; int oneof_case_offset;
int unknown_fields_offset; int unknown_fields_offset;
int extensions_offset; int extensions_offset;
int is_default_instance_offset;
// Not owned by the TypeInfo. // Not owned by the TypeInfo.
DynamicMessageFactory* factory; // The factory that created this object. DynamicMessageFactory* factory; // The factory that created this object.
@ -316,6 +317,11 @@ void DynamicMessage::SharedCtor() {
uint32(0); uint32(0);
} }
if (type_info_->is_default_instance_offset != -1) {
*reinterpret_cast<bool*>(
OffsetToPointer(type_info_->is_default_instance_offset)) = false;
}
new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet;
if (type_info_->extensions_offset != -1) { if (type_info_->extensions_offset != -1) {
@ -532,6 +538,14 @@ void DynamicMessage::CrossLinkPrototypes() {
factory->GetPrototypeNoLock(field->message_type()); factory->GetPrototypeNoLock(field->message_type());
} }
} }
// Set as the default instance -- this affects field-presence semantics for
// proto3.
if (type_info_->is_default_instance_offset != -1) {
void* is_default_instance_ptr =
OffsetToPointer(type_info_->is_default_instance_offset);
*reinterpret_cast<bool*>(is_default_instance_ptr) = true;
}
} }
Message* DynamicMessage::New() const { Message* DynamicMessage::New() const {
@ -641,11 +655,24 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
size = AlignOffset(size); size = AlignOffset(size);
// Next the has_bits, which is an array of uint32s. // Next the has_bits, which is an array of uint32s.
if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
type_info->has_bits_offset = -1;
} else {
type_info->has_bits_offset = size; type_info->has_bits_offset = size;
int has_bits_array_size = int has_bits_array_size =
DivideRoundingUp(type->field_count(), bitsizeof(uint32)); DivideRoundingUp(type->field_count(), bitsizeof(uint32));
size += has_bits_array_size * sizeof(uint32); size += has_bits_array_size * sizeof(uint32);
size = AlignOffset(size); size = AlignOffset(size);
}
// The is_default_instance member, if any.
if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
type_info->is_default_instance_offset = size;
size += sizeof(bool);
size = AlignOffset(size);
} else {
type_info->is_default_instance_offset = -1;
}
// The oneof_case, if any. It is an array of uint32s. // The oneof_case, if any. It is an array of uint32s.
if (type->oneof_decl_count() > 0) { if (type->oneof_decl_count() > 0) {
@ -731,7 +758,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
type_info->pool, type_info->pool,
this, this,
type_info->size, type_info->size,
-1 /* arena_offset */)); -1 /* arena_offset */,
type_info->is_default_instance_offset));
} else { } else {
type_info->reflection.reset( type_info->reflection.reset(
new GeneratedMessageReflection( new GeneratedMessageReflection(
@ -744,7 +772,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
type_info->pool, type_info->pool,
this, this,
type_info->size, type_info->size,
-1 /* arena_offset */)); -1 /* arena_offset */,
type_info->is_default_instance_offset));
} }
// Cross link prototypes. // Cross link prototypes.
prototype->CrossLinkPrototypes(); prototype->CrossLinkPrototypes();

@ -46,6 +46,7 @@
#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/test_util.h> #include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h> #include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_no_field_presence.pb.h>
#include <google/protobuf/testing/googletest.h> #include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -65,6 +66,8 @@ class DynamicMessageTest : public testing::Test {
const Message* packed_prototype_; const Message* packed_prototype_;
const Descriptor* oneof_descriptor_; const Descriptor* oneof_descriptor_;
const Message* oneof_prototype_; const Message* oneof_prototype_;
const Descriptor* proto3_descriptor_;
const Message* proto3_prototype_;
DynamicMessageTest(): factory_(&pool_) {} DynamicMessageTest(): factory_(&pool_) {}
@ -76,16 +79,20 @@ class DynamicMessageTest : public testing::Test {
FileDescriptorProto unittest_file; FileDescriptorProto unittest_file;
FileDescriptorProto unittest_import_file; FileDescriptorProto unittest_import_file;
FileDescriptorProto unittest_import_public_file; FileDescriptorProto unittest_import_public_file;
FileDescriptorProto unittest_no_field_presence_file;
unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file); unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
unittest_import::ImportMessage::descriptor()->file()->CopyTo( unittest_import::ImportMessage::descriptor()->file()->CopyTo(
&unittest_import_file); &unittest_import_file);
unittest_import::PublicImportMessage::descriptor()->file()->CopyTo( unittest_import::PublicImportMessage::descriptor()->file()->CopyTo(
&unittest_import_public_file); &unittest_import_public_file);
proto2_nofieldpresence_unittest::TestAllTypes::descriptor()->
file()->CopyTo(&unittest_no_field_presence_file);
ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL); ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL);
ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL); ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL);
ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL); ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL);
ASSERT_TRUE(pool_.BuildFile(unittest_no_field_presence_file) != NULL);
descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes"); descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
ASSERT_TRUE(descriptor_ != NULL); ASSERT_TRUE(descriptor_ != NULL);
@ -105,6 +112,12 @@ class DynamicMessageTest : public testing::Test {
pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2"); pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2");
ASSERT_TRUE(oneof_descriptor_ != NULL); ASSERT_TRUE(oneof_descriptor_ != NULL);
oneof_prototype_ = factory_.GetPrototype(oneof_descriptor_); oneof_prototype_ = factory_.GetPrototype(oneof_descriptor_);
proto3_descriptor_ =
pool_.FindMessageTypeByName(
"proto2_nofieldpresence_unittest.TestAllTypes");
ASSERT_TRUE(proto3_descriptor_ != NULL);
proto3_prototype_ = factory_.GetPrototype(proto3_descriptor_);
} }
}; };
@ -233,6 +246,40 @@ TEST_F(DynamicMessageTest, Arena) {
// Return without freeing: should not leak. // Return without freeing: should not leak.
} }
TEST_F(DynamicMessageTest, Proto3) {
Message* message = proto3_prototype_->New();
const Reflection* refl = message->GetReflection();
const Descriptor* desc = message->GetDescriptor();
// Just test a single primtive and single message field here to make sure we
// are getting the no-field-presence semantics elsewhere. DynamicMessage uses
// GeneratedMessageReflection under the hood, so the rest should be fine as
// long as GMR recognizes that we're using a proto3 message.
const FieldDescriptor* optional_int32 =
desc->FindFieldByName("optional_int32");
const FieldDescriptor* optional_msg =
desc->FindFieldByName("optional_nested_message");
EXPECT_TRUE(optional_int32 != NULL);
EXPECT_TRUE(optional_msg != NULL);
EXPECT_EQ(false, refl->HasField(*message, optional_int32));
refl->SetInt32(message, optional_int32, 42);
EXPECT_EQ(true, refl->HasField(*message, optional_int32));
refl->SetInt32(message, optional_int32, 0);
EXPECT_EQ(false, refl->HasField(*message, optional_int32));
EXPECT_EQ(false, refl->HasField(*message, optional_msg));
refl->MutableMessage(message, optional_msg);
EXPECT_EQ(true, refl->HasField(*message, optional_msg));
delete refl->ReleaseMessage(message, optional_msg);
EXPECT_EQ(false, refl->HasField(*message, optional_msg));
// Also ensure that the default instance handles field presence properly.
EXPECT_EQ(false, refl->HasField(*proto3_prototype_, optional_msg));
delete message;
}
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google

@ -193,7 +193,8 @@ GeneratedMessageReflection::GeneratedMessageReflection(
const DescriptorPool* descriptor_pool, const DescriptorPool* descriptor_pool,
MessageFactory* factory, MessageFactory* factory,
int object_size, int object_size,
int arena_offset) int arena_offset,
int is_default_instance_offset)
: descriptor_ (descriptor), : descriptor_ (descriptor),
default_instance_ (default_instance), default_instance_ (default_instance),
offsets_ (offsets), offsets_ (offsets),
@ -201,6 +202,7 @@ GeneratedMessageReflection::GeneratedMessageReflection(
unknown_fields_offset_(unknown_fields_offset), unknown_fields_offset_(unknown_fields_offset),
extensions_offset_(extensions_offset), extensions_offset_(extensions_offset),
arena_offset_ (arena_offset), arena_offset_ (arena_offset),
is_default_instance_offset_(is_default_instance_offset),
object_size_ (object_size), object_size_ (object_size),
descriptor_pool_ ((descriptor_pool == NULL) ? descriptor_pool_ ((descriptor_pool == NULL) ?
DescriptorPool::generated_pool() : DescriptorPool::generated_pool() :
@ -220,7 +222,8 @@ GeneratedMessageReflection::GeneratedMessageReflection(
const DescriptorPool* descriptor_pool, const DescriptorPool* descriptor_pool,
MessageFactory* factory, MessageFactory* factory,
int object_size, int object_size,
int arena_offset) int arena_offset,
int is_default_instance_offset)
: descriptor_ (descriptor), : descriptor_ (descriptor),
default_instance_ (default_instance), default_instance_ (default_instance),
default_oneof_instance_ (default_oneof_instance), default_oneof_instance_ (default_oneof_instance),
@ -230,6 +233,7 @@ GeneratedMessageReflection::GeneratedMessageReflection(
unknown_fields_offset_(unknown_fields_offset), unknown_fields_offset_(unknown_fields_offset),
extensions_offset_(extensions_offset), extensions_offset_(extensions_offset),
arena_offset_ (arena_offset), arena_offset_ (arena_offset),
is_default_instance_offset_(is_default_instance_offset),
object_size_ (object_size), object_size_ (object_size),
descriptor_pool_ ((descriptor_pool == NULL) ? descriptor_pool_ ((descriptor_pool == NULL) ?
DescriptorPool::generated_pool() : DescriptorPool::generated_pool() :
@ -1829,6 +1833,17 @@ GeneratedMessageReflection::MutableInternalMetadataWithArena(
return reinterpret_cast<InternalMetadataWithArena*>(ptr); return reinterpret_cast<InternalMetadataWithArena*>(ptr);
} }
inline bool
GeneratedMessageReflection::GetIsDefaultInstance(
const Message& message) const {
if (is_default_instance_offset_ == kHasNoDefaultInstanceField) {
return false;
}
const void* ptr = reinterpret_cast<const uint8*>(&message) +
is_default_instance_offset_;
return *reinterpret_cast<const bool*>(ptr);
}
// Simple accessors for manipulating has_bits_. // Simple accessors for manipulating has_bits_.
inline bool GeneratedMessageReflection::HasBit( inline bool GeneratedMessageReflection::HasBit(
const Message& message, const FieldDescriptor* field) const { const Message& message, const FieldDescriptor* field) const {
@ -1836,7 +1851,8 @@ inline bool GeneratedMessageReflection::HasBit(
// proto3: no has-bits. All fields present except messages, which are // proto3: no has-bits. All fields present except messages, which are
// present only if their message-field pointer is non-NULL. // present only if their message-field pointer is non-NULL.
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
return GetRaw<const Message*>(message, field) != NULL; return !GetIsDefaultInstance(message) &&
GetRaw<const Message*>(message, field) != NULL;
} else { } else {
// Non-message field (and non-oneof, since that was handled in HasField() // Non-message field (and non-oneof, since that was handled in HasField()
// before calling us), and singular (again, checked in HasField). So, this // before calling us), and singular (again, checked in HasField). So, this
@ -2082,7 +2098,8 @@ GeneratedMessageReflection::NewGeneratedMessageReflection(
const void* default_oneof_instance, const void* default_oneof_instance,
int oneof_case_offset, int oneof_case_offset,
int object_size, int object_size,
int arena_offset) { int arena_offset,
int is_default_instance_offset) {
return new GeneratedMessageReflection(descriptor, return new GeneratedMessageReflection(descriptor,
default_instance, default_instance,
offsets, offsets,
@ -2094,7 +2111,8 @@ GeneratedMessageReflection::NewGeneratedMessageReflection(
DescriptorPool::generated_pool(), DescriptorPool::generated_pool(),
MessageFactory::generated_factory(), MessageFactory::generated_factory(),
object_size, object_size,
arena_offset); arena_offset,
is_default_instance_offset);
} }
GeneratedMessageReflection* GeneratedMessageReflection*
@ -2106,7 +2124,8 @@ GeneratedMessageReflection::NewGeneratedMessageReflection(
int unknown_fields_offset, int unknown_fields_offset,
int extensions_offset, int extensions_offset,
int object_size, int object_size,
int arena_offset) { int arena_offset,
int is_default_instance_offset) {
return new GeneratedMessageReflection(descriptor, return new GeneratedMessageReflection(descriptor,
default_instance, default_instance,
offsets, offsets,
@ -2116,7 +2135,8 @@ GeneratedMessageReflection::NewGeneratedMessageReflection(
DescriptorPool::generated_pool(), DescriptorPool::generated_pool(),
MessageFactory::generated_factory(), MessageFactory::generated_factory(),
object_size, object_size,
arena_offset); arena_offset,
is_default_instance_offset);
} }
} // namespace internal } // namespace internal

@ -136,7 +136,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const DescriptorPool* pool, const DescriptorPool* pool,
MessageFactory* factory, MessageFactory* factory,
int object_size, int object_size,
int arena_offset); int arena_offset,
int is_default_instance_offset = -1);
// Similar with the construction above. Call this construction if the // Similar with the construction above. Call this construction if the
// message has oneof definition. // message has oneof definition.
@ -173,7 +174,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const DescriptorPool* pool, const DescriptorPool* pool,
MessageFactory* factory, MessageFactory* factory,
int object_size, int object_size,
int arena_offset); int arena_offset,
int is_default_instance_offset = -1);
~GeneratedMessageReflection(); ~GeneratedMessageReflection();
// Shorter-to-call helpers for the above two constructions that work if the // Shorter-to-call helpers for the above two constructions that work if the
@ -190,7 +192,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const void* default_oneof_instance, const void* default_oneof_instance,
int oneof_case_offset, int oneof_case_offset,
int object_size, int object_size,
int arena_offset); int arena_offset,
int is_default_instance_offset = -1);
static GeneratedMessageReflection* NewGeneratedMessageReflection( static GeneratedMessageReflection* NewGeneratedMessageReflection(
const Descriptor* descriptor, const Descriptor* descriptor,
@ -200,7 +203,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
int unknown_fields_offset, int unknown_fields_offset,
int extensions_offset, int extensions_offset,
int object_size, int object_size,
int arena_offset); int arena_offset,
int is_default_instance_offset = -1);
// implements Reflection ------------------------------------------- // implements Reflection -------------------------------------------
@ -414,8 +418,11 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
int unknown_fields_offset_; int unknown_fields_offset_;
int extensions_offset_; int extensions_offset_;
int arena_offset_; int arena_offset_;
int is_default_instance_offset_;
int object_size_; int object_size_;
static const int kHasNoDefaultInstanceField = -1;
const DescriptorPool* descriptor_pool_; const DescriptorPool* descriptor_pool_;
MessageFactory* message_factory_; MessageFactory* message_factory_;
@ -446,6 +453,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
inline internal::InternalMetadataWithArena* inline internal::InternalMetadataWithArena*
MutableInternalMetadataWithArena(Message* message) const; MutableInternalMetadataWithArena(Message* message) const;
inline bool GetIsDefaultInstance(const Message& message) const;
inline bool HasBit(const Message& message, inline bool HasBit(const Message& message,
const FieldDescriptor* field) const; const FieldDescriptor* field) const;
inline void SetBit(Message* message, inline void SetBit(Message* message,

@ -269,6 +269,10 @@ TEST(NoFieldPresenceTest, MessageFieldPresenceTest) {
EXPECT_EQ(true, message.has_optional_lazy_message()); EXPECT_EQ(true, message.has_optional_lazy_message());
message.clear_optional_lazy_message(); message.clear_optional_lazy_message();
EXPECT_EQ(false, message.has_optional_lazy_message()); EXPECT_EQ(false, message.has_optional_lazy_message());
// Test field presence of a message field on the default instance.
EXPECT_EQ(false, proto2_nofieldpresence_unittest::TestAllTypes::
default_instance().has_optional_nested_message());
} }
TEST(NoFieldPresenceTest, ReflectionHasFieldTest) { TEST(NoFieldPresenceTest, ReflectionHasFieldTest) {
@ -287,6 +291,13 @@ TEST(NoFieldPresenceTest, ReflectionHasFieldTest) {
EXPECT_EQ(false, r->HasField(message, field)); EXPECT_EQ(false, r->HasField(message, field));
} }
// Test field presence of a message field on the default instance.
const google::protobuf::FieldDescriptor* msg_field =
desc->FindFieldByName("optional_nested_message");
EXPECT_EQ(false, r->HasField(
proto2_nofieldpresence_unittest::TestAllTypes::
default_instance(), msg_field));
// Fill all fields, expect everything to report true (check oneofs below). // Fill all fields, expect everything to report true (check oneofs below).
FillValues(&message); FillValues(&message);
for (int i = 0; i < desc->field_count(); i++) { for (int i = 0; i < desc->field_count(); i++) {

Loading…
Cancel
Save