|  | @@ -89,6 +89,13 @@ $ ./src/protoc test_proto3_optional.proto --cpp_out=.
 | 
	
		
			
				|  |  |  $
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +The experimental check will be removed  in a future release, once we are ready
 | 
	
		
			
				|  |  | +to make this feature generally available. Ideally this will happen for the 3.13
 | 
	
		
			
				|  |  | +release of protobuf, sometime in mid-2020, but there is not a specific date set
 | 
	
		
			
				|  |  | +for this yet. Some of the timing will depend on feedback we get from the
 | 
	
		
			
				|  |  | +community, so if you have questions or concerns please get in touch via a
 | 
	
		
			
				|  |  | +GitHub issue.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  ### Signaling That Your Code Generator Supports Proto3 Optional
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  If you now try to invoke your own code generator with the test proto, you will
 | 
	
	
		
			
				|  | @@ -246,8 +253,44 @@ bool IterateOverOneofs(const google::protobuf::Descriptor* message) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ## Updating Reflection
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -If your implementation supports protobuf reflection, there are a few changes
 | 
	
		
			
				|  |  | -that you need to make:
 | 
	
		
			
				|  |  | +If your implementation offers reflection, there are a few other changes to make:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +### API Changes
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +The API for reflecting over fields and oneofs should make the following changes.
 | 
	
		
			
				|  |  | +These match the changes implemented in C++ reflection.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +1. Add a `FieldDescriptor::has_presence()` method returning `bool`
 | 
	
		
			
				|  |  | +   (adjusted to your language's naming convention).  This should return true
 | 
	
		
			
				|  |  | +   for all fields that have explicit presence, as documented in
 | 
	
		
			
				|  |  | +   [docs/field_presence](field_presence.md).  In particular, this includes
 | 
	
		
			
				|  |  | +   fields in a oneof, proto2 scalar fields, and proto3 `optional` fields.
 | 
	
		
			
				|  |  | +   This accessor will allow users to query what fields have presence without
 | 
	
		
			
				|  |  | +   thinking about the difference between proto2 and proto3.
 | 
	
		
			
				|  |  | +2. As a corollary of (1), please do *not* expose an accessor for the
 | 
	
		
			
				|  |  | +   `FieldDescriptorProto.proto3_optional` field. We want to avoid having
 | 
	
		
			
				|  |  | +   users implement any proto2/proto3-specific logic. Users should use the
 | 
	
		
			
				|  |  | +   `has_presence()` function instead.
 | 
	
		
			
				|  |  | +3. You may also wish to add a `FieldDescriptor::has_optional_keyword()` method
 | 
	
		
			
				|  |  | +   returning `bool`, which indicates whether the `optional` keyword is present.
 | 
	
		
			
				|  |  | +   Message fields will always return `true` for `has_presence()`, so this method
 | 
	
		
			
				|  |  | +   can allow a user to know whether the user wrote `optional` or not. It can
 | 
	
		
			
				|  |  | +   occasionally be useful to have this information, even though it does not
 | 
	
		
			
				|  |  | +   change the presence semantics of the field.
 | 
	
		
			
				|  |  | +4. If your reflection API may be used for a code generator, you may wish to
 | 
	
		
			
				|  |  | +   implement methods to help users tell the difference between real and
 | 
	
		
			
				|  |  | +   synthetic oneofs.  In particular:
 | 
	
		
			
				|  |  | +   - `OneofDescriptor::is_synthetic()`: returns true if this is a synthetic
 | 
	
		
			
				|  |  | +     oneof.
 | 
	
		
			
				|  |  | +   - `FieldDescriptor::real_containing_oneof()`: like `containing_oneof()`,
 | 
	
		
			
				|  |  | +     but returns `nullptr` if the oneof is synthetic.
 | 
	
		
			
				|  |  | +   - `Descriptor::real_oneof_decl_count()`: like `oneof_decl_count()`, but
 | 
	
		
			
				|  |  | +     returns the number of real oneofs only.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +### Implementation Changes
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Proto3 `optional` fields and synthetic oneofs must work correctly when
 | 
	
		
			
				|  |  | +reflected on. Specifically:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  1. Reflection for synthetic oneofs should work properly. Even though synthetic
 | 
	
		
			
				|  |  |     oneofs do not really exist in the message, you can still make reflection work
 | 
	
	
		
			
				|  | @@ -272,3 +315,36 @@ fields in a oneof.
 | 
	
		
			
				|  |  |  So the best way to test your reflection changes is to try round-tripping a
 | 
	
		
			
				|  |  |  message through text format, JSON, or some other reflection-based parser and
 | 
	
		
			
				|  |  |  serializer, if you have one.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +### Validating Descriptors
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +If your reflection implementation supports loading descriptors at runtime,
 | 
	
		
			
				|  |  | +you must verify that all synthetic oneofs are ordered after all "real" oneofs.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Here is the code that implements this validation step in C++, for inspiration:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +```c++
 | 
	
		
			
				|  |  | +  // Validation that runs for each message.
 | 
	
		
			
				|  |  | +  // 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;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +```
 |