| 
					
				 | 
			
			
				@@ -19,8 +19,56 @@ using System; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace Google.ProtocolBuffers { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /// TODO(jonskeet): Copy docs from Java 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// A table of known extensions, searchable by name or field number.  When 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// parsing a protocol message that might have extensions, you must provide 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// an <see cref="ExtensionRegistry"/> in which you have registered any extensions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// that you want to be able to parse.  Otherwise, those extensions will just 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// be treated like unknown fields. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// <example> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// For example, if you had the <c>.proto</c> file: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// option java_class = "MyProto"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// message Foo { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///   extensions 1000 to max; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// extend Foo { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ///   optional int32 bar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// Then you might write code like: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// <code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// registry.Add(MyProto.Bar); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// </code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// </example> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// <remarks> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// <para>You might wonder why this is necessary. Two alternatives might come to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// mind. First, you might imagine a system where generated extensions are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// automatically registered when their containing classes are loaded. This 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// is a popular technique, but is bad design; among other things, it creates a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// situation where behavior can change depending on what classes happen to be 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// loaded. It also introduces a security vulnerability, because an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// unprivileged class could cause its code to be called unexpectedly from a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// privileged class by registering itself as an extension of the right type. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// </para> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// <para>Another option you might consider is lazy parsing: do not parse an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// extension until it is first requested, at which point the caller must 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// provide a type to use. This introduces a different set of problems. First, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// it would require a mutex lock any time an extension was accessed, which 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// would be slow. Second, corrupt data would not be detected until first 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// access, at which point it would be much harder to deal with it. Third, it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// could violate the expectation that message objects are immutable, since the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// type provided could be any arbitrary message class. An unprivileged user 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// could take advantage of this to inject a mutable object into a message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// belonging to privileged code and create mischief.</para> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// </remarks> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   public sealed class ExtensionRegistry { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private static readonly ExtensionRegistry empty = new ExtensionRegistry( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -140,7 +188,7 @@ namespace Google.ProtocolBuffers { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           && field.IsOptional 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           && field.ExtensionScope == field.MessageType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // This is an extension of a MessageSet type defined within the extension 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // type's own scope.  For backwards-compatibility, allow it to be looked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // type's own scope. For backwards-compatibility, allow it to be looked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // up by type name. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         extensionsByName[field.MessageType.FullName] = extension; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 |