// 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) getExtension:(Class) clazz fieldNumber:(NSInteger) fieldNumber; /* @protected */ - (id) initWithClassMap:(NSDictionary*) classMap; - (id) keyForClass:(Class) clazz; @end