Skip to content

Commit 4483c6b

Browse files
authored
Lazily resolve features for proto2 and proto3 for compatibility with old open source gencode that does not invoke feature resolution from gencode static init. (#16907)
PiperOrigin-RevId: 634804242
1 parent 0a05aa8 commit 4483c6b

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

java/core/src/main/java/com/google/protobuf/Descriptors.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ public Type getType() {
12981298
// (custom options) into unknown fields.
12991299
if (type == Type.MESSAGE
13001300
&& this.features != null
1301-
&& this.features.getMessageEncoding() == FeatureSet.MessageEncoding.DELIMITED) {
1301+
&& getFeatures().getMessageEncoding() == FeatureSet.MessageEncoding.DELIMITED) {
13021302
return Type.GROUP;
13031303
}
13041304
return type;
@@ -1319,13 +1319,13 @@ public boolean needsUtf8Check() {
13191319
// Always enforce strict UTF-8 checking for map fields.
13201320
return true;
13211321
}
1322-
if (this.features
1322+
if (getFeatures()
13231323
.getExtension(JavaFeaturesProto.java_)
13241324
.getUtf8Validation()
13251325
.equals(JavaFeatures.Utf8Validation.VERIFY)) {
13261326
return true;
13271327
}
1328-
return this.features.getUtf8Validation().equals(FeatureSet.Utf8Validation.VERIFY);
1328+
return getFeatures().getUtf8Validation().equals(FeatureSet.Utf8Validation.VERIFY);
13291329
}
13301330

13311331
public boolean isMapField() {
@@ -1341,14 +1341,14 @@ && isRepeated()
13411341

13421342
/** Is this field declared required? */
13431343
public boolean isRequired() {
1344-
return this.features.getFieldPresence()
1344+
return getFeatures().getFieldPresence()
13451345
== DescriptorProtos.FeatureSet.FieldPresence.LEGACY_REQUIRED;
13461346
}
13471347

13481348
/** Is this field declared optional? */
13491349
public boolean isOptional() {
13501350
return proto.getLabel() == FieldDescriptorProto.Label.LABEL_OPTIONAL
1351-
&& this.features.getFieldPresence()
1351+
&& getFeatures().getFieldPresence()
13521352
!= DescriptorProtos.FeatureSet.FieldPresence.LEGACY_REQUIRED;
13531353
}
13541354

@@ -1367,7 +1367,7 @@ public boolean isPacked() {
13671367
if (!isPackable()) {
13681368
return false;
13691369
}
1370-
return this.features
1370+
return getFeatures()
13711371
.getRepeatedFieldEncoding()
13721372
.equals(FeatureSet.RepeatedFieldEncoding.PACKED);
13731373
}
@@ -1467,7 +1467,7 @@ public boolean hasPresence() {
14671467
|| getType() == Type.GROUP
14681468
|| isExtension()
14691469
|| getContainingOneof() != null
1470-
|| this.features.getFieldPresence() != DescriptorProtos.FeatureSet.FieldPresence.IMPLICIT;
1470+
|| getFeatures().getFieldPresence() != DescriptorProtos.FeatureSet.FieldPresence.IMPLICIT;
14711471
}
14721472

14731473
/**
@@ -1476,7 +1476,8 @@ public boolean hasPresence() {
14761476
* been upgraded to editions.
14771477
*/
14781478
boolean isGroupLike() {
1479-
if (features.getMessageEncoding() != DescriptorProtos.FeatureSet.MessageEncoding.DELIMITED) {
1479+
if (getFeatures().getMessageEncoding()
1480+
!= DescriptorProtos.FeatureSet.MessageEncoding.DELIMITED) {
14801481
// Groups are always tag-delimited.
14811482
return false;
14821483
}
@@ -1577,7 +1578,7 @@ public boolean legacyEnumFieldTreatedAsClosed() {
15771578
}
15781579

15791580
return getType() == Type.ENUM
1580-
&& (this.features.getExtension(JavaFeaturesProto.java_).getLegacyClosedEnum()
1581+
&& (getFeatures().getExtension(JavaFeaturesProto.java_).getLegacyClosedEnum()
15811582
|| enumType.isClosed());
15821583
}
15831584

@@ -2115,7 +2116,7 @@ public FileDescriptor getFile() {
21152116
* handling quirks.
21162117
*/
21172118
public boolean isClosed() {
2118-
return this.features.getEnumType() == DescriptorProtos.FeatureSet.EnumType.CLOSED;
2119+
return getFeatures().getEnumType() == DescriptorProtos.FeatureSet.EnumType.CLOSED;
21192120
}
21202121

21212122
/** If this is a nested type, get the outer descriptor, otherwise null. */
@@ -2811,6 +2812,17 @@ boolean hasInferredLegacyProtoFeatures() {
28112812

28122813
void validateFeatures() throws DescriptorValidationException {}
28132814

2815+
FeatureSet getFeatures() {
2816+
// TODO: Remove lazy resolution of unresolved features for legacy syntax for
2817+
// compatibility with older <4.26.x gencode in the next breaking release.
2818+
if (this.features == null
2819+
&& (getFile().getEdition() == Edition.EDITION_PROTO2
2820+
|| getFile().getEdition() == Edition.EDITION_PROTO3)) {
2821+
getFile().resolveAllFeaturesImmutable();
2822+
}
2823+
return this.features;
2824+
}
2825+
28142826
GenericDescriptor parent;
28152827
volatile FeatureSet features;
28162828
}

0 commit comments

Comments
 (0)