@@ -1298,7 +1298,7 @@ public Type getType() {
1298
1298
// (custom options) into unknown fields.
1299
1299
if (type == Type .MESSAGE
1300
1300
&& this .features != null
1301
- && this . features .getMessageEncoding () == FeatureSet .MessageEncoding .DELIMITED ) {
1301
+ && getFeatures () .getMessageEncoding () == FeatureSet .MessageEncoding .DELIMITED ) {
1302
1302
return Type .GROUP ;
1303
1303
}
1304
1304
return type ;
@@ -1319,13 +1319,13 @@ public boolean needsUtf8Check() {
1319
1319
// Always enforce strict UTF-8 checking for map fields.
1320
1320
return true ;
1321
1321
}
1322
- if (this . features
1322
+ if (getFeatures ()
1323
1323
.getExtension (JavaFeaturesProto .java_ )
1324
1324
.getUtf8Validation ()
1325
1325
.equals (JavaFeatures .Utf8Validation .VERIFY )) {
1326
1326
return true ;
1327
1327
}
1328
- return this . features .getUtf8Validation ().equals (FeatureSet .Utf8Validation .VERIFY );
1328
+ return getFeatures () .getUtf8Validation ().equals (FeatureSet .Utf8Validation .VERIFY );
1329
1329
}
1330
1330
1331
1331
public boolean isMapField () {
@@ -1341,14 +1341,14 @@ && isRepeated()
1341
1341
1342
1342
/** Is this field declared required? */
1343
1343
public boolean isRequired () {
1344
- return this . features .getFieldPresence ()
1344
+ return getFeatures () .getFieldPresence ()
1345
1345
== DescriptorProtos .FeatureSet .FieldPresence .LEGACY_REQUIRED ;
1346
1346
}
1347
1347
1348
1348
/** Is this field declared optional? */
1349
1349
public boolean isOptional () {
1350
1350
return proto .getLabel () == FieldDescriptorProto .Label .LABEL_OPTIONAL
1351
- && this . features .getFieldPresence ()
1351
+ && getFeatures () .getFieldPresence ()
1352
1352
!= DescriptorProtos .FeatureSet .FieldPresence .LEGACY_REQUIRED ;
1353
1353
}
1354
1354
@@ -1367,7 +1367,7 @@ public boolean isPacked() {
1367
1367
if (!isPackable ()) {
1368
1368
return false ;
1369
1369
}
1370
- return this . features
1370
+ return getFeatures ()
1371
1371
.getRepeatedFieldEncoding ()
1372
1372
.equals (FeatureSet .RepeatedFieldEncoding .PACKED );
1373
1373
}
@@ -1467,7 +1467,7 @@ public boolean hasPresence() {
1467
1467
|| getType () == Type .GROUP
1468
1468
|| isExtension ()
1469
1469
|| getContainingOneof () != null
1470
- || this . features .getFieldPresence () != DescriptorProtos .FeatureSet .FieldPresence .IMPLICIT ;
1470
+ || getFeatures () .getFieldPresence () != DescriptorProtos .FeatureSet .FieldPresence .IMPLICIT ;
1471
1471
}
1472
1472
1473
1473
/**
@@ -1476,7 +1476,8 @@ public boolean hasPresence() {
1476
1476
* been upgraded to editions.
1477
1477
*/
1478
1478
boolean isGroupLike () {
1479
- if (features .getMessageEncoding () != DescriptorProtos .FeatureSet .MessageEncoding .DELIMITED ) {
1479
+ if (getFeatures ().getMessageEncoding ()
1480
+ != DescriptorProtos .FeatureSet .MessageEncoding .DELIMITED ) {
1480
1481
// Groups are always tag-delimited.
1481
1482
return false ;
1482
1483
}
@@ -1577,7 +1578,7 @@ public boolean legacyEnumFieldTreatedAsClosed() {
1577
1578
}
1578
1579
1579
1580
return getType () == Type .ENUM
1580
- && (this . features .getExtension (JavaFeaturesProto .java_ ).getLegacyClosedEnum ()
1581
+ && (getFeatures () .getExtension (JavaFeaturesProto .java_ ).getLegacyClosedEnum ()
1581
1582
|| enumType .isClosed ());
1582
1583
}
1583
1584
@@ -2115,7 +2116,7 @@ public FileDescriptor getFile() {
2115
2116
* handling quirks.
2116
2117
*/
2117
2118
public boolean isClosed () {
2118
- return this . features .getEnumType () == DescriptorProtos .FeatureSet .EnumType .CLOSED ;
2119
+ return getFeatures () .getEnumType () == DescriptorProtos .FeatureSet .EnumType .CLOSED ;
2119
2120
}
2120
2121
2121
2122
/** If this is a nested type, get the outer descriptor, otherwise null. */
@@ -2811,6 +2812,17 @@ boolean hasInferredLegacyProtoFeatures() {
2811
2812
2812
2813
void validateFeatures () throws DescriptorValidationException {}
2813
2814
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
+
2814
2826
GenericDescriptor parent ;
2815
2827
volatile FeatureSet features ;
2816
2828
}
0 commit comments