From a594141cc408b972c9ffe2bcf14958174d0a4fe4 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 14 Feb 2023 11:02:41 -0800 Subject: [PATCH] Document known quirks of EnumDescriptor::is_closed() when importing across files with different syntaxes. PiperOrigin-RevId: 509581394 --- .../java/com/google/protobuf/Descriptors.java | 25 +++++++++++++------ python/google/protobuf/descriptor.py | 24 +++++++++++++----- src/google/protobuf/descriptor.h | 14 ++++++++++- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index e6503a05d7ec6..e5b973f15804b 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -303,9 +303,7 @@ public static FileDescriptor buildFrom(FileDescriptorProto proto, FileDescriptor * two messages were defined with the same name. */ public static FileDescriptor buildFrom( - FileDescriptorProto proto, - FileDescriptor[] dependencies, - boolean allowUnknownDependencies) + FileDescriptorProto proto, FileDescriptor[] dependencies, boolean allowUnknownDependencies) throws DescriptorValidationException { // Building descriptors involves two steps: translating and linking. // In the translation step (implemented by FileDescriptor's @@ -462,9 +460,9 @@ public static FileDescriptor internalBuildGeneratedFileFrom( } /** - * This method is to be called by generated code only. It updates the - * FileDescriptorProto associated with the descriptor by parsing it again with the given - * ExtensionRegistry. This is needed to recognize custom options. + * This method is to be called by generated code only. It updates the FileDescriptorProto + * associated with the descriptor by parsing it again with the given ExtensionRegistry. This is + * needed to recognize custom options. */ public static void internalUpdateFileDescriptor( FileDescriptor descriptor, ExtensionRegistry registry) { @@ -1778,10 +1776,23 @@ public FileDescriptor getFile() { *

Closed enum means that it: * *

+ * + *

WARNING: Some runtimes currently have a quirk where non-closed enums are treated as closed + * when used as the type of fields defined in a `syntax = proto2;` file. This quirk is not + * present in all runtimes; as of writing, we know that: + * + *

+ * + *

Care should be taken when using this function to respect the target runtime's enum + * handling quirks. */ public boolean isClosed() { return getFile().getSyntax() != Syntax.PROTO3; diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index e5d547a3bbebc..fcb87cab5581f 100755 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -739,13 +739,25 @@ def __init__(self, name, full_name, filename, values, @property def is_closed(self): - """If the enum is closed. + """Returns true whether this is a "closed" enum. - closed enum means: - - Has a fixed set of named values. - - Encountering values not in this set causes them to be treated as - unknown fields. - - The first value (i.e., the default) may be nonzero. + This means that it: + - Has a fixed set of values, rather than being equivalent to an int32. + - Encountering values not in this set causes them to be treated as unknown + fields. + - The first value (i.e., the default) may be nonzero. + + WARNING: Some runtimes currently have a quirk where non-closed enums are + treated as closed when used as the type of fields defined in a + `syntax = proto2;` file. This quirk is not present in all runtimes; as of + writing, we know that: + + - C++, Java, and C++-based Python share this quirk. + - UPB and UPB-based Python do not. + - PHP and Ruby treat all enums as open regardless of declaration. + + Care should be taken when using this function to respect the target + runtime's enum handling quirks. """ return self.file.syntax == 'proto2' diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 1caf5c194b8b7..f6359e845cc75 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -1151,10 +1151,22 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { bool is_placeholder() const; // Returns true whether this is a "closed" enum, meaning that it: - // - Has a fixed set of named values. + // - Has a fixed set of values, rather than being equivalent to an int32. // - Encountering values not in this set causes them to be treated as unknown // fields. // - The first value (i.e., the default) may be nonzero. + // + // WARNING: Some runtimes currently have a quirk where non-closed enums are + // treated as closed when used as the type of fields defined in a + // `syntax = proto2;` file. This quirk is not present in all runtimes; as of + // writing, we know that: + // + // - C++, Java, and C++-based Python share this quirk. + // - UPB and UPB-based Python do not. + // - PHP and Ruby treat all enums as open regardless of declaration. + // + // Care should be taken when using this function to respect the target + // runtime's enum handling quirks. bool is_closed() const; // Reserved fields -------------------------------------------------