diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index f5e1befca3..424d969005 100644 Binary files a/csharp/src/Google.Protobuf.Test/testprotos.pb and b/csharp/src/Google.Protobuf.Test/testprotos.pb differ diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index 8b39573d7c..c9ba6328b9 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -2074,10 +2074,21 @@ namespace Google.Protobuf.Reflection { /// If true, this is a proto3 "optional". When a proto3 field is optional, it /// tracks presence regardless of field type. /// - /// For message fields this doesn't create any semantic change, since - /// non-repeated message fields always track presence. However it still + /// When proto3_optional is true, this field must be belong to a oneof to + /// signal to old proto3 clients that presence is tracked for this field. This + /// oneof is known as a "synthetic" oneof, and this field must be its sole + /// member (each proto3 optional field gets its own synthetic oneof). Synthetic + /// oneofs exist in the descriptor only, and do not generate any API. Synthetic + /// oneofs must be ordered after all "real" oneofs. + /// + /// For message fields, proto3_optional doesn't create any semantic change, + /// since non-repeated message fields always track presence. However it still /// indicates the semantic detail of whether the user wrote "optional" or not. - /// This can be useful for round-tripping the .proto file. + /// This can be useful for round-tripping the .proto file. For consistency we + /// give message fields a synthetic oneof also, even though it is not required + /// to track presence. This is especially important because the parser can't + /// tell if a field is a message or an enum, so it must always create a + /// synthetic oneof. /// /// Proto2 optional fields do not set this flag, because they already indicate /// optional with `LABEL_OPTIONAL`. diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php index e00488e12e..b43d988141 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php @@ -96,10 +96,20 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. - * For message fields this doesn't create any semantic change, since - * non-repeated message fields always track presence. However it still + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. - * This can be useful for round-tripping the .proto file. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * @@ -147,10 +157,20 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * @type bool $proto3_optional * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. - * For message fields this doesn't create any semantic change, since - * non-repeated message fields always track presence. However it still + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. - * This can be useful for round-tripping the .proto file. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * } @@ -495,10 +515,20 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. - * For message fields this doesn't create any semantic change, since - * non-repeated message fields always track presence. However it still + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. - * This can be useful for round-tripping the .proto file. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * @@ -513,10 +543,20 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. - * For message fields this doesn't create any semantic change, since - * non-repeated message fields always track presence. However it still + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. - * This can be useful for round-tripping the .proto file. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index e39764d0eb..8e9ed86034 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -33,11 +33,14 @@ #include +#include // A Python header file. + #include #include #include #include -#include // A Python header file. + +#include #ifndef PyVarObject_HEAD_INIT #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, @@ -456,7 +459,7 @@ static PyObject* GetClassAttribute(CMessageClass *self, PyObject* name) { Py_ssize_t attr_size; static const char kSuffix[] = "_FIELD_NUMBER"; if (PyString_AsStringAndSize(name, &attr, &attr_size) >= 0 && - strings::EndsWith(StringPiece(attr, attr_size), kSuffix)) { + HasSuffixString(StringPiece(attr, attr_size), kSuffix)) { std::string field_name(attr, attr_size - sizeof(kSuffix) + 1); LowerString(&field_name); diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 6a73ab8048..f95e14e58b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -156,7 +156,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator( default: return new RepeatedPrimitiveFieldGenerator(field, options); } - } else if (InRealOneof(field)) { + } else if (field->real_containing_oneof()) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: return new MessageOneofFieldGenerator(field, options, scc_analyzer); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 61f81429ca..e2961e50e3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -34,6 +34,7 @@ #include +#include #include #include #include diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 7aeffb0f00..976823afa8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -1151,7 +1151,7 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, return UsingImplicitWeakFields(field->file(), options) && field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_required() && !field->is_map() && !field->is_extension() && - !InRealOneof(field) && + !field->real_containing_oneof() && !IsWellKnownMessage(field->message_type()->file()) && field->message_type()->file()->name() != "net/proto2/proto/descriptor.proto" && @@ -1474,7 +1474,7 @@ class ParseLoopGenerator { GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME && // For now only use arena string for strings with empty defaults. field->default_value_string().empty() && - !IsStringInlined(field, options_) && !InRealOneof(field) && + !IsStringInlined(field, options_) && !field->real_containing_oneof() && ctype == FieldOptions::STRING) { GenerateArenaString(field); } else { @@ -1580,7 +1580,7 @@ class ParseLoopGenerator { FieldName(field)); } } else if (IsLazy(field, options_)) { - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { format_( "if (!_internal_has_$1$()) {\n" " clear_$2$();\n" @@ -1684,7 +1684,7 @@ class ParseLoopGenerator { field->type() == FieldDescriptor::TYPE_SINT64)) { zigzag = "ZigZag"; } - if (field->is_repeated() || InRealOneof(field)) { + if (field->is_repeated() || field->real_containing_oneof()) { std::string prefix = field->is_repeated() ? "add" : "set"; format_( "_internal_$1$_$2$($pi_ns$::ReadVarint$3$$4$(&ptr));\n" @@ -1706,7 +1706,7 @@ class ParseLoopGenerator { case WireFormatLite::WIRETYPE_FIXED32: case WireFormatLite::WIRETYPE_FIXED64: { std::string type = PrimitiveTypeName(options_, field->cpp_type()); - if (field->is_repeated() || InRealOneof(field)) { + if (field->is_repeated() || field->real_containing_oneof()) { std::string prefix = field->is_repeated() ? "add" : "set"; format_( "_internal_$1$_$2$($pi_ns$::UnalignedLoad<$3$>(ptr));\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index ec57cb4a5c..988e6092c1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -444,23 +444,6 @@ inline bool HasHasbit(const FieldDescriptor* field) { !field->options().weak(); } -inline bool InRealOneof(const FieldDescriptor* field) { - return field->containing_oneof() && - !field->containing_oneof()->is_synthetic(); -} - -// In practice all synthetic oneofs should be at the end of the list, but we -// decline to depend on this for correctness of the function. -inline int RealOneofCount(const Descriptor* descriptor) { - int count = 0; - for (int i = 0; i < descriptor->oneof_decl_count(); i++) { - if (!descriptor->oneof_decl(i)->is_synthetic()) { - count++; - } - } - return count; -} - // Returns true if 'enum' semantics are such that unknown values are preserved // in the enum field itself, rather than going to the UnknownFieldSet. inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { @@ -886,14 +869,6 @@ struct OneOfRangeImpl { using value_type = const OneofDescriptor*; using difference_type = int; - explicit Iterator(const Descriptor* _descriptor) - : idx(-1), descriptor(_descriptor) { - Next(); - } - - Iterator(int _idx, const Descriptor* _descriptor) - : idx(_idx), descriptor(_descriptor) {} - value_type operator*() { return descriptor->oneof_decl(idx); } friend bool operator==(const Iterator& a, const Iterator& b) { @@ -905,23 +880,18 @@ struct OneOfRangeImpl { } Iterator& operator++() { - Next(); + idx++; return *this; } - void Next() { - do { - idx++; - } while (idx < descriptor->oneof_decl_count() && - descriptor->oneof_decl(idx)->is_synthetic()); - } - int idx; const Descriptor* descriptor; }; - Iterator begin() const { return Iterator(descriptor); } - Iterator end() const { return {descriptor->oneof_decl_count(), descriptor}; } + Iterator begin() const { return {0, descriptor}; } + Iterator end() const { + return {descriptor->real_oneof_decl_count(), descriptor}; + } const Descriptor* descriptor; }; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 33be14694e..1cc089196e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -226,7 +226,7 @@ bool EmitFieldNonDefaultCondition(io::Printer* printer, } format.Indent(); return true; - } else if (InRealOneof(field)) { + } else if (field->real_containing_oneof()) { format("if (_internal_has_$name$()) {\n"); format.Indent(); return true; @@ -282,7 +282,7 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, bool HasPrivateHasMethod(const FieldDescriptor* field) { // Only for oneofs in message types with no field presence. has_$name$(), // based on the oneof case, is still useful internally for generated code. - return (!HasFieldPresence(field->file()) && InRealOneof(field)); + return (!HasFieldPresence(field->file()) && field->real_containing_oneof()); } // TODO(ckennelly): Cull these exclusions if/when these protos do not have @@ -597,7 +597,7 @@ MessageGenerator::MessageGenerator( if (IsWeak(field, options_)) { num_weak_fields_++; - } else if (!InRealOneof(field)) { + } else if (!field->real_containing_oneof()) { optimized_order_.push_back(field); } } @@ -677,7 +677,7 @@ void MessageGenerator::AddGenerators( void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { Formatter format(printer, variables_); // optimized_fields_ does not contain fields where - // InRealOneof(field) == true + // field->real_containing_oneof() // so we need to iterate over those as well. // // We place the non-oneof fields in optimized_order_, as that controls the @@ -689,7 +689,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(), optimized_order_.end()); for (auto field : FieldRange(descriptor_)) { - if (!InRealOneof(field) && !field->options().weak() && + if (!field->real_containing_oneof() && !field->options().weak() && IsFieldUsed(field, options_)) { continue; } @@ -922,7 +922,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, format.Indent(); - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { // Clear this field only if it is the active field in this oneof, // otherwise ignore format("if (_internal_has_$name$()) {\n"); @@ -983,7 +983,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { ? ".weak" : ""); } - } else if (InRealOneof(field)) { + } else if (field->real_containing_oneof()) { format.Set("field_name", UnderscoresToCamelCase(field->name(), true)); format.Set("oneof_name", field->containing_oneof()->name()); format.Set("oneof_index", @@ -1485,7 +1485,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { for (auto field : FieldRange(descriptor_)) { // set_has_***() generated in all oneofs. if (!field->is_repeated() && !field->options().weak() && - InRealOneof(field)) { + field->real_containing_oneof()) { format("void set_has_$1$();\n", FieldName(field)); } } @@ -1594,12 +1594,11 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { } // Generate _oneof_case_. - int count = RealOneofCount(descriptor_); - if (count > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { format( "$uint32$ _oneof_case_[$1$];\n" "\n", - count); + descriptor_->real_oneof_decl_count()); } if (num_weak_fields_) { @@ -1695,7 +1694,7 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); } - if (RealOneofCount(descriptor_) > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n"); } else { format("-1, // no _oneof_case_\n"); @@ -1755,7 +1754,7 @@ uint32 CalcFieldNum(const FieldGenerator& generator, } } - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kOneOf); } else if (field->is_packed()) { @@ -1764,7 +1763,7 @@ uint32 CalcFieldNum(const FieldGenerator& generator, } else if (field->is_repeated()) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kRepeated); - } else if (HasHasbit(field) || InRealOneof(field) || is_a_map) { + } else if (HasHasbit(field) || field->real_containing_oneof() || is_a_map) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kPresence); } else { @@ -1859,7 +1858,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { } std::string classfieldname = FieldName(field); - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { classfieldname = field->containing_oneof()->name(); } format.Set("field_name", classfieldname); @@ -1895,7 +1894,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { type = internal::FieldMetadata::kSpecial; ptr = "reinterpret_cast(::" + variables_["proto_ns"] + "::internal::LazyFieldSerializer"; - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { ptr += "OneOf"; } else if (!HasHasbit(field)) { ptr += "NoPresence"; @@ -1912,7 +1911,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { "reinterpret_cast(::$proto_ns$::internal::WeakFieldSerializer)},\n", tag); - } else if (InRealOneof(field)) { + } else if (field->real_containing_oneof()) { format.Set("oneofoffset", sizeof(uint32) * field->containing_oneof()->index()); format( @@ -1972,10 +1971,10 @@ void MessageGenerator::GenerateDefaultInstanceInitializer( if (!field->is_repeated() && !IsLazy(field, options_) && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - (!InRealOneof(field) || + (!field->real_containing_oneof() || HasDescriptorMethods(descriptor_->file(), options_))) { std::string name; - if (InRealOneof(field) || field->options().weak()) { + if (field->real_containing_oneof() || field->options().weak()) { name = "_" + classname_ + "_default_instance_."; } else { name = @@ -2007,7 +2006,7 @@ void MessageGenerator::GenerateDefaultInstanceInitializer( " $1$::internal_default_instance());\n", FieldMessageTypeName(field, options_)); } - } else if (InRealOneof(field) && + } else if (field->real_containing_oneof() && HasDescriptorMethods(descriptor_->file(), options_)) { field_generators_.get(field).GenerateConstructorCode(printer); } @@ -2118,7 +2117,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter::SaveState saver(&format); std::map vars; SetCommonFieldVariables(field, &vars, options_); - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { SetCommonOneofFieldVariables(field, &vars); } format.AddMap(vars); @@ -2129,7 +2128,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { GenerateStructors(printer); format("\n"); - if (RealOneofCount(descriptor_) > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { GenerateOneofClear(printer); format("\n"); } @@ -2258,8 +2257,8 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { processing_type |= static_cast( field->is_repeated() ? internal::kRepeatedMask : 0); - processing_type |= - static_cast(InRealOneof(field) ? internal::kOneofMask : 0); + processing_type |= static_cast( + field->real_containing_oneof() ? internal::kOneofMask : 0); if (field->is_map()) { processing_type = internal::TYPE_MAP; @@ -2269,7 +2268,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { WireFormat::TagSize(field->number(), field->type()); std::map vars; - if (InRealOneof(field)) { + if (field->real_containing_oneof()) { vars["name"] = field->containing_oneof()->name(); vars["presence"] = StrCat(field->containing_oneof()->index()); } else { @@ -2400,7 +2399,7 @@ std::pair MessageGenerator::GenerateOffsets( } else { format("~0u, // no _extensions_\n"); } - if (RealOneofCount(descriptor_) > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n"); } else { format("~0u, // no _oneof_case_\n"); @@ -2418,13 +2417,13 @@ std::pair MessageGenerator::GenerateOffsets( } const int kNumGenericOffsets = 5; // the number of fixed offsets above const size_t offsets = kNumGenericOffsets + descriptor_->field_count() + - RealOneofCount(descriptor_) - num_stripped; + descriptor_->real_oneof_decl_count() - num_stripped; size_t entries = offsets; for (auto field : FieldRange(descriptor_)) { if (!IsFieldUsed(field, options_)) { continue; } - if (InRealOneof(field) || field->options().weak()) { + if (field->real_containing_oneof() || field->options().weak()) { format("offsetof($classtype$DefaultTypeInternal, $1$_)", FieldName(field)); } else { @@ -2444,7 +2443,7 @@ std::pair MessageGenerator::GenerateOffsets( format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name()); count++; } - GOOGLE_CHECK_EQ(count, RealOneofCount(descriptor_)); + GOOGLE_CHECK_EQ(count, descriptor_->real_oneof_decl_count()); if (IsMapEntryMessage(descriptor_)) { entries += 2; @@ -2656,7 +2655,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { for (auto field : optimized_order_) { GOOGLE_DCHECK(IsFieldUsed(field, options_)); bool has_arena_constructor = field->is_repeated(); - if (!InRealOneof(field) && + if (!field->real_containing_oneof() && (IsLazy(field, options_) || IsStringPiece(field, options_))) { has_arena_constructor = true; } @@ -3122,8 +3121,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { format("swap($1$_, other->$1$_);\n", oneof->name()); } - int count = RealOneofCount(descriptor_); - for (int i = 0; i < count; i++) { + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i); } @@ -3572,7 +3570,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( if (eager_ || MustFlush(field)) { Flush(); } - if (!InRealOneof(field)) { + if (!field->real_containing_oneof()) { // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields. if (!field->options().weak() && !field->is_repeated() && !eager_) { @@ -4014,7 +4012,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { } else if (field->options().weak()) { continue; } else { - GOOGLE_CHECK(!InRealOneof(field)); + GOOGLE_CHECK(!field->real_containing_oneof()); format( "if (_internal_has_$1$()) {\n" " if (!$1$_->IsInitialized()) return false;\n" @@ -4054,7 +4052,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && scc_analyzer_->HasRequiredFields(field->message_type())) { - GOOGLE_CHECK(!(field->options().weak() || !InRealOneof(field))); + GOOGLE_CHECK(!(field->options().weak() || !field->real_containing_oneof())); if (field->options().weak()) { // Just skip. } else { diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 43fe860620..a21c4c7fbb 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -501,7 +501,7 @@ void StringFieldGenerator::GenerateMessageClearingCode( void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (SupportsArenas(descriptor_) || InRealOneof(descriptor_)) { + if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) { // TODO(gpike): improve this format("_internal_set_$name$(from._internal_$name$());\n"); } else { @@ -545,7 +545,7 @@ void StringFieldGenerator::GenerateCopyConstructorCode( format.Indent(); - if (SupportsArenas(descriptor_) || InRealOneof(descriptor_)) { + if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) { // TODO(gpike): improve this format( "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n" diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index bc4bbe8f6f..2fc7aadff6 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -94,7 +94,9 @@ bool CollectExtensions(const Message& message, FieldDescriptorSet* extensions) { reflection->ListFields(message, &fields); for (int i = 0; i < fields.size(); i++) { - if (fields[i]->is_extension()) extensions->insert(fields[i]); + if (fields[i]->is_extension()) { + extensions->insert(fields[i]); + } if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { if (fields[i]->is_repeated()) { diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index 302296d56d..70a840e6da 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -106,9 +106,8 @@ class MockCodeGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const override; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; uint64 GetSupportedFeatures() const override; void SuppressFeatures(uint64 features); diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index a0f5a2cac4..d92cd55873 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -783,8 +783,7 @@ bool Parser::ParseMessageDefinition( } for (auto& field : *message->mutable_field()) { - if (field.proto3_optional() && - field.type() != FieldDescriptorProto::TYPE_MESSAGE) { + if (field.proto3_optional()) { std::string oneof_name = field.name(); // Prepend 'XXXXX_' until we are no longer conflicting. diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 82e5a785f5..fb1aee1617 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -69,10 +69,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { virtual ~Generator(); // CodeGenerator methods. - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, - GeneratorContext* generator_context, - std::string* error) const override; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; uint64 GetSupportedFeatures() const override; diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index b94e925e45..1ec38c1de5 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -5500,6 +5500,42 @@ void DescriptorBuilder::CrossLinkMessage(Descriptor* message, message->field(i); } } + + for (int i = 0; i < message->field_count(); i++) { + const FieldDescriptor* field = message->field(i); + if (field->proto3_optional_) { + if (!field->containing_oneof() || + !field->containing_oneof()->is_synthetic()) { + AddError(message->full_name(), proto.field(i), + DescriptorPool::ErrorCollector::OTHER, + "Fields with proto3_optional set must be " + "a member of a one-field oneof"); + } + } + } + + // Synthetic oneofs must be last. + int first_synthetic = -1; + for (int i = 0; i < message->oneof_decl_count(); i++) { + const OneofDescriptor* oneof = message->oneof_decl(i); + if (oneof->is_synthetic()) { + if (first_synthetic == -1) { + first_synthetic = i; + } + } else { + if (first_synthetic != -1) { + AddError(message->full_name(), proto.oneof_decl(i), + DescriptorPool::ErrorCollector::OTHER, + "Synthetic oneofs must be after all other oneofs"); + } + } + } + + if (first_synthetic == -1) { + message->real_oneof_decl_count_ = message->oneof_decl_count_; + } else { + message->real_oneof_decl_count_ = first_synthetic; + } } void DescriptorBuilder::CrossLinkExtensionRange( diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index e84bc3eac5..322d5a4663 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -337,6 +337,10 @@ class PROTOBUF_EXPORT Descriptor { // The number of oneofs in this message type. int oneof_decl_count() const; + // The number of oneofs in this message type, excluding synthetic oneofs. + // Real oneofs always come first, so iterating up to real_oneof_decl_cout() + // will yield all real oneofs. + int real_oneof_decl_count() const; // Get a oneof by index, where 0 <= index < oneof_decl_count(). // These are returned in the order they were defined in the .proto file. const OneofDescriptor* oneof_decl(int index) const; @@ -526,6 +530,7 @@ class PROTOBUF_EXPORT Descriptor { int field_count_; int oneof_decl_count_; + int real_oneof_decl_count_; int nested_type_count_; int enum_type_count_; int extension_range_count_; @@ -745,6 +750,10 @@ class PROTOBUF_EXPORT FieldDescriptor { // nullptr. const OneofDescriptor* containing_oneof() const; + // If the field is a member of a non-synthetic oneof, returns the descriptor + // for the oneof, otherwise returns nullptr. + const OneofDescriptor* real_containing_oneof() const; + // If the field is a member of a oneof, returns the index in that oneof. int index_in_oneof() const; @@ -1972,6 +1981,7 @@ PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, real_oneof_decl_count, int) PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) @@ -2166,9 +2176,15 @@ inline bool FieldDescriptor::has_optional_keyword() const { !containing_oneof()); } +inline const OneofDescriptor* FieldDescriptor::real_containing_oneof() const { + return containing_oneof_ && !containing_oneof_->is_synthetic() + ? containing_oneof_ + : nullptr; +} + inline bool FieldDescriptor::is_singular_with_presence() const { if (is_repeated()) return false; - if (containing_oneof() && !containing_oneof()->is_synthetic()) return false; + if (real_containing_oneof()) return false; return cpp_type() == CPPTYPE_MESSAGE || proto3_optional_ || file()->syntax() == FileDescriptor::SYNTAX_PROTO2; } diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index deb8f6894d..d29fdec5e5 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -217,10 +217,21 @@ message FieldDescriptorProto { // If true, this is a proto3 "optional". When a proto3 field is optional, it // tracks presence regardless of field type. // - // For message fields this doesn't create any semantic change, since - // non-repeated message fields always track presence. However it still + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still // indicates the semantic detail of whether the user wrote "optional" or not. - // This can be useful for round-tripping the .proto file. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. // // Proto2 optional fields do not set this flag, because they already indicate // optional with `LABEL_OPTIONAL`. diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 971d5b7ab4..fd5237172f 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -737,7 +737,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( uint32* has_bits_indices = new uint32[type->field_count()]; for (int i = 0; i < type->field_count(); i++) { // Initialize to -1, fields that need a hasbit will overwrite. - has_bits_indices[i] = -1; + has_bits_indices[i] = static_cast(-1); } type_info->has_bits_indices.reset(has_bits_indices); } diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 7aab17f8a9..e2eae772c6 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -169,7 +169,7 @@ struct ReflectionSchema { // Bit index within the bit array of hasbits. Bit order is low-to-high. uint32 HasBitIndex(const FieldDescriptor* field) const { - if (has_bits_offset_ == -1) return -1; + if (has_bits_offset_ == -1) return static_cast(-1); GOOGLE_DCHECK(HasHasbits()); return has_bit_indices_[field->index()]; } diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h index 80f215880c..ae13b363ef 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.h +++ b/src/google/protobuf/generated_message_table_driven_lite.h @@ -280,9 +280,13 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, } utf8_string_data = field->Get(); } break; + default: + PROTOBUF_ASSUME(false); } break; } + default: + PROTOBUF_ASSUME(false); } if (kValidateUtf8) { @@ -322,6 +326,8 @@ inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, SetOneofField(msg, presence, presence_index, offset, field_number, value); break; + default: + PROTOBUF_ASSUME(false); } } else { UnknownFieldHandler::Varint(msg, table, tag, value); @@ -406,9 +412,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, const unsigned char processing_type = data->processing_type; if (data->normal_wiretype == static_cast(wire_type)) { - // TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate - // the bounds check on processing_type. - switch (processing_type) { #define HANDLE_TYPE(TYPE, CPPTYPE) \ case (WireFormatLite::TYPE_##TYPE): { \ @@ -739,7 +742,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, return true; } default: - break; + PROTOBUF_ASSUME(false); } } else if (data->packed_wiretype == static_cast(wire_type)) { // Non-packable fields have their packed_wiretype masked with @@ -751,8 +754,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type); GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type); - // TODO(ckennelly): Use a computed goto on GCC/LLVM. - // // Mask out kRepeatedMask bit, allowing the jump table to be smaller. switch (static_cast(processing_type ^ kRepeatedMask)) { @@ -825,7 +826,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, GOOGLE_DCHECK(false); return false; default: - break; + PROTOBUF_ASSUME(false); } } else { if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { diff --git a/src/google/protobuf/stubs/statusor.h b/src/google/protobuf/stubs/statusor.h index e8e403a677..c02e89a9f0 100644 --- a/src/google/protobuf/stubs/statusor.h +++ b/src/google/protobuf/stubs/statusor.h @@ -153,6 +153,7 @@ class StatusOr { // If you need to initialize a T object from the stored value, // ConsumeValueOrDie() may be more efficient. const T& ValueOrDie() const; + const T& value () const; private: Status status_; @@ -254,6 +255,14 @@ inline const T& StatusOr::ValueOrDie() const { } return value_; } + +template +inline const T& StatusOr::value() const { + if (!status_.ok()) { + internal::StatusOrHelper::Crash(status_); + } + return value_; +} } // namespace util } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index 6c18b6cd21..0d886068a6 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -173,7 +173,7 @@ StatusOr DataPiece::ToDouble() const { if (str_ == "-Infinity") return -std::numeric_limits::infinity(); if (str_ == "NaN") return std::numeric_limits::quiet_NaN(); StatusOr value = StringToNumber(safe_strtod); - if (value.ok() && !std::isfinite(value.ValueOrDie())) { + if (value.ok() && !std::isfinite(value.value())) { // safe_strtod converts out-of-range values to +inf/-inf, but we want // to report them as errors. return InvalidArgument(StrCat("\"", str_, "\"")); @@ -289,7 +289,7 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, StatusOr int_value = ToInt32(); if (int_value.ok()) { if (const google::protobuf::EnumValue* enum_value = - FindEnumValueByNumberOrNull(enum_type, int_value.ValueOrDie())) { + FindEnumValueByNumberOrNull(enum_type, int_value.value())) { return enum_value->number(); } } diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index 828c86887e..a78a862eb0 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -52,7 +52,7 @@ T ConvertTo(StringPiece value, StatusOr (DataPiece::*converter_fn)() const, T default_value) { if (value.empty()) return default_value; StatusOr result = (DataPiece(value, true).*converter_fn)(); - return result.ok() ? result.ValueOrDie() : default_value; + return result.ok() ? result.value() : default_value; } } // namespace @@ -290,7 +290,7 @@ const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType( if (!sub_type.ok()) { GOOGLE_LOG(WARNING) << "Cannot resolve type '" << sub_field.type_url() << "'."; } else { - return sub_type.ValueOrDie(); + return sub_type.value(); } break; } @@ -354,7 +354,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // "field" is of an unknown type. GOOGLE_LOG(WARNING) << "Cannot resolve type '" << field.type_url() << "'."; } else { - const google::protobuf::Type* found_type = found_result.ValueOrDie(); + const google::protobuf::Type* found_type = found_result.value(); is_map = IsMap(field, *found_type); if (!is_map) { @@ -587,7 +587,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, name == "@type") { util::StatusOr data_string = data.ToString(); if (data_string.ok()) { - const std::string& string_value = data_string.ValueOrDie(); + const std::string& string_value = data_string.value(); // If the type of current_ is "Any" and its "@type" field is being set // here, sets the type of current_ to be the type specified by the // "@type". @@ -596,7 +596,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, if (!found_type.ok()) { GOOGLE_LOG(WARNING) << "Failed to resolve type '" << string_value << "'."; } else { - current_->set_type(found_type.ValueOrDie()); + current_->set_type(found_type.value()); } current_->set_is_any(true); // If the "@type" field is placed after other fields, we should populate diff --git a/src/google/protobuf/util/internal/object_writer.cc b/src/google/protobuf/util/internal/object_writer.cc index 72f658745b..b7667b6b16 100644 --- a/src/google/protobuf/util/internal/object_writer.cc +++ b/src/google/protobuf/util/internal/object_writer.cc @@ -42,35 +42,35 @@ void ObjectWriter::RenderDataPieceTo(const DataPiece& data, StringPiece name, ObjectWriter* ow) { switch (data.type()) { case DataPiece::TYPE_INT32: { - ow->RenderInt32(name, data.ToInt32().ValueOrDie()); + ow->RenderInt32(name, data.ToInt32().value()); break; } case DataPiece::TYPE_INT64: { - ow->RenderInt64(name, data.ToInt64().ValueOrDie()); + ow->RenderInt64(name, data.ToInt64().value()); break; } case DataPiece::TYPE_UINT32: { - ow->RenderUint32(name, data.ToUint32().ValueOrDie()); + ow->RenderUint32(name, data.ToUint32().value()); break; } case DataPiece::TYPE_UINT64: { - ow->RenderUint64(name, data.ToUint64().ValueOrDie()); + ow->RenderUint64(name, data.ToUint64().value()); break; } case DataPiece::TYPE_DOUBLE: { - ow->RenderDouble(name, data.ToDouble().ValueOrDie()); + ow->RenderDouble(name, data.ToDouble().value()); break; } case DataPiece::TYPE_FLOAT: { - ow->RenderFloat(name, data.ToFloat().ValueOrDie()); + ow->RenderFloat(name, data.ToFloat().value()); break; } case DataPiece::TYPE_BOOL: { - ow->RenderBool(name, data.ToBool().ValueOrDie()); + ow->RenderBool(name, data.ToBool().value()); break; } case DataPiece::TYPE_STRING: { - ow->RenderString(name, data.ToString().ValueOrDie()); + ow->RenderString(name, data.ToString().value()); break; } case DataPiece::TYPE_BYTES: { diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index f2ee022456..ea95932fd6 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -124,7 +124,7 @@ inline Status WriteInt32(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr i32 = data.ToInt32(); if (i32.ok()) { - WireFormatLite::WriteInt32(field_number, i32.ValueOrDie(), stream); + WireFormatLite::WriteInt32(field_number, i32.value(), stream); } return i32.status(); } @@ -134,7 +134,7 @@ inline Status WriteSFixed32(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr i32 = data.ToInt32(); if (i32.ok()) { - WireFormatLite::WriteSFixed32(field_number, i32.ValueOrDie(), stream); + WireFormatLite::WriteSFixed32(field_number, i32.value(), stream); } return i32.status(); } @@ -144,7 +144,7 @@ inline Status WriteSInt32(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr i32 = data.ToInt32(); if (i32.ok()) { - WireFormatLite::WriteSInt32(field_number, i32.ValueOrDie(), stream); + WireFormatLite::WriteSInt32(field_number, i32.value(), stream); } return i32.status(); } @@ -154,7 +154,7 @@ inline Status WriteFixed32(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr u32 = data.ToUint32(); if (u32.ok()) { - WireFormatLite::WriteFixed32(field_number, u32.ValueOrDie(), stream); + WireFormatLite::WriteFixed32(field_number, u32.value(), stream); } return u32.status(); } @@ -164,7 +164,7 @@ inline Status WriteUInt32(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr u32 = data.ToUint32(); if (u32.ok()) { - WireFormatLite::WriteUInt32(field_number, u32.ValueOrDie(), stream); + WireFormatLite::WriteUInt32(field_number, u32.value(), stream); } return u32.status(); } @@ -174,7 +174,7 @@ inline Status WriteInt64(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr i64 = data.ToInt64(); if (i64.ok()) { - WireFormatLite::WriteInt64(field_number, i64.ValueOrDie(), stream); + WireFormatLite::WriteInt64(field_number, i64.value(), stream); } return i64.status(); } @@ -184,7 +184,7 @@ inline Status WriteSFixed64(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr i64 = data.ToInt64(); if (i64.ok()) { - WireFormatLite::WriteSFixed64(field_number, i64.ValueOrDie(), stream); + WireFormatLite::WriteSFixed64(field_number, i64.value(), stream); } return i64.status(); } @@ -194,7 +194,7 @@ inline Status WriteSInt64(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr i64 = data.ToInt64(); if (i64.ok()) { - WireFormatLite::WriteSInt64(field_number, i64.ValueOrDie(), stream); + WireFormatLite::WriteSInt64(field_number, i64.value(), stream); } return i64.status(); } @@ -204,7 +204,7 @@ inline Status WriteFixed64(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr u64 = data.ToUint64(); if (u64.ok()) { - WireFormatLite::WriteFixed64(field_number, u64.ValueOrDie(), stream); + WireFormatLite::WriteFixed64(field_number, u64.value(), stream); } return u64.status(); } @@ -214,7 +214,7 @@ inline Status WriteUInt64(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr u64 = data.ToUint64(); if (u64.ok()) { - WireFormatLite::WriteUInt64(field_number, u64.ValueOrDie(), stream); + WireFormatLite::WriteUInt64(field_number, u64.value(), stream); } return u64.status(); } @@ -224,7 +224,7 @@ inline Status WriteDouble(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr d = data.ToDouble(); if (d.ok()) { - WireFormatLite::WriteDouble(field_number, d.ValueOrDie(), stream); + WireFormatLite::WriteDouble(field_number, d.value(), stream); } return d.status(); } @@ -234,7 +234,7 @@ inline Status WriteFloat(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr f = data.ToFloat(); if (f.ok()) { - WireFormatLite::WriteFloat(field_number, f.ValueOrDie(), stream); + WireFormatLite::WriteFloat(field_number, f.value(), stream); } return f.status(); } @@ -244,7 +244,7 @@ inline Status WriteBool(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr b = data.ToBool(); if (b.ok()) { - WireFormatLite::WriteBool(field_number, b.ValueOrDie(), stream); + WireFormatLite::WriteBool(field_number, b.value(), stream); } return b.status(); } @@ -264,7 +264,7 @@ inline Status WriteString(int field_number, const DataPiece& data, CodedOutputStream* stream) { StatusOr s = data.ToString(); if (s.ok()) { - WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream); + WireFormatLite::WriteString(field_number, s.value(), stream); } return s.status(); } @@ -602,7 +602,7 @@ Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, case_insensitive_enum_parsing, ignore_unknown_values, &is_unknown_enum_value); if (e.ok() && !is_unknown_enum_value) { - WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream); + WireFormatLite::WriteEnum(field_number, e.value(), stream); } return e.status(); } @@ -704,8 +704,8 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( break; } default: // TYPE_GROUP or TYPE_MESSAGE - status = Status(util::error::INVALID_ARGUMENT, - data.ToString().ValueOrDie()); + status = + Status(util::error::INVALID_ARGUMENT, data.ToString().value()); } if (!status.ok()) { diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index fad62f5a23..80b1defd7a 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -647,7 +647,7 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, resolved_type.status().message()); } // nested_type cannot be null at this time. - const google::protobuf::Type* nested_type = resolved_type.ValueOrDie(); + const google::protobuf::Type* nested_type = resolved_type.value(); io::ArrayInputStream zero_copy_stream(value.data(), value.size()); io::CodedInputStream in_stream(&zero_copy_stream); diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 752c3f0b77..527d5e70da 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -334,7 +334,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { invalid_ = true; return; } - type_url_ = s.ValueOrDie(); + type_url_ = s.value(); } // Resolve the type url, and report an error if we failed to resolve it. StatusOr resolved_type = @@ -345,7 +345,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { return; } // At this point, type is never null. - const google::protobuf::Type* type = resolved_type.ValueOrDie(); + const google::protobuf::Type* type = resolved_type.value(); well_known_type_render_ = FindTypeRenderer(type_url_); if (well_known_type_render_ != nullptr || @@ -897,7 +897,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(int_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(int_value.value()), true)); return Status(); } } @@ -910,7 +910,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(int_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(int_value.value()), true)); return Status(); } } @@ -924,8 +924,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, StatusOr int_value = data.ToInt64(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( - "string_value", - DataPiece(StrCat(int_value.ValueOrDie()), true)); + "string_value", DataPiece(StrCat(int_value.value()), true)); return Status(); } } @@ -939,8 +938,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, StatusOr int_value = data.ToUint64(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( - "string_value", - DataPiece(StrCat(int_value.ValueOrDie()), true)); + "string_value", DataPiece(StrCat(int_value.value()), true)); return Status(); } } @@ -953,7 +951,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, if (float_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(float_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(float_value.value()), true)); return Status(); } } @@ -966,7 +964,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, if (double_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(double_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(double_value.value()), true)); return Status(); } } diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 818df64172..e8b2103855 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -81,7 +81,7 @@ class TypeInfoForTypeResolver : public TypeInfo { const google::protobuf::Type* GetTypeByTypeUrl( StringPiece type_url) const override { StatusOrType result = ResolveTypeUrl(type_url); - return result.ok() ? result.ValueOrDie() : NULL; + return result.ok() ? result.value() : NULL; } const google::protobuf::Enum* GetEnumByTypeUrl( @@ -89,7 +89,7 @@ class TypeInfoForTypeResolver : public TypeInfo { std::map::iterator it = cached_enums_.find(type_url); if (it != cached_enums_.end()) { - return it->second.ok() ? it->second.ValueOrDie() : NULL; + return it->second.ok() ? it->second.value() : NULL; } // Stores the string value so it can be referenced using StringPiece in the // cached_enums_ map. @@ -102,7 +102,7 @@ class TypeInfoForTypeResolver : public TypeInfo { StatusOrEnum result = status.ok() ? StatusOrEnum(enum_type.release()) : StatusOrEnum(status); cached_enums_[string_type_url] = result; - return result.ok() ? result.ValueOrDie() : NULL; + return result.ok() ? result.value() : NULL; } const google::protobuf::Field* FindField( @@ -134,7 +134,7 @@ class TypeInfoForTypeResolver : public TypeInfo { cached_types->begin(); it != cached_types->end(); ++it) { if (it->second.ok()) { - delete it->second.ValueOrDie(); + delete it->second.value(); } } }