// Copyright 2008 Cyrus Najmabadi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * A table of known extensions, searchable by name or field number. When * parsing a protocol message that might have extensions, you must provide * an {@code 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. * *
For example, if you had the {@code .proto} file: * *
* option java_class = "MyProto"; * * message Foo { * extensions 1000 to max; * } * * extend Foo { * optional int32 bar; * } ** * Then you might write code like: * *
* ExtensionRegistry registry = ExtensionRegistry.newInstance(); * registry.add(MyProto.bar); * MyProto.Foo message = MyProto.Foo.parseFrom(input, registry); ** *
Background: * *
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. * *
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 unpriviledged user
* could take advantage of this to inject a mutable object into a message
* belonging to priviledged code and create mischief.
*
* @author Cyrus Najmabadi
*/
@protocol PBExtensionField;
@interface PBExtensionRegistry : NSObject {
@protected
NSDictionary* classMap;
}
+ (PBExtensionRegistry*) emptyRegistry;
- (id