title: How can I get the type of a protobuf extension property?
body: <p>I have a build system that has to pack protobufs from users' inputs. The user fills in fields in a form, submits them, and the build system packs the protobufs and sends them along their way. The build system has to be unaware of the types it is processing. Otherwise, every time the project team changed their .protos, I'd have to make build changes to support them.</p>
  
  <p>The vast majority of this works. The .protos might look like this:</p>
  
  <pre><code>#dataobj_base.proto
  message DataObj {
    extensions 100 to 199;
    optional string property1 = 1;
  }
  
  #dataobj.proto
  message DataObjExtension {
    optional string ext_property1 = 1;
  }  
  
  extend DataObj {
    optional DataObjExtension generic_extension = 100;
  }
  </code></pre>
  
  <p>....and this is simple enough to support. Up to this point, my build system has accessed the generic_extension object by knowing the name of the type it is writing, and nothing more. I could import DataObj_pb2 and DataObjExtension_pb2 and use them like this:</p>
  
  <pre><code>def do_the_thing(type_name, property1, ext_property1):
    #type_name, in this case, is 'DataObj'
    game_module = (
      importlib.import_module('generated_protobufs.{}_pb2'.format(type_name)))
    ext_module = (
      importlib.import_module('generated_protobufs.{}Extension_pb2'.format(type_name)))
    instance_constructor = getattr(game_module, type_name)
    instance = instance_constructor()
  
    #instance is now an instance of DataObj
    instance.property1 = property1
    setattr(pb_instance.Extensions[ext_module.generic_extension],
            property_name, property_value)
  }
  </code></pre>
  
  <p>That works great, but the project team want to derive multiple types from the same base. It breaks if I need two different types that work with the DataObj "base." I'd like to be able to do this:</p>
  
  <pre><code>extend DataObj {
    optional SomeOtherBaseObj generic_extension = 100;
  }
  </code></pre>
  
  <p>The trouble is that, in my python code, I need to know the type of <code>generic_extension</code>. If I were writing the code with knowledge of the type I was processing, I would do:</p>
  
  <pre><code>extensions = instance.Extensions[SomeOtherBaseObj_pb2.generic_extension]
  </code></pre>
  
  <p>...and <code>extensions.__class__</code> would tell me everything I need to know.</p>
  
  <p>Is there a way to get the names of any of the properties in the extension without first knowing anything about them - including (especially) their type info? There are a million ways that I could redesign the .protos to be a huge improvement, but there's already a considerable base of code that depends on them as they are. Adding fields would be fine, and I might be able to sell minor modifications, but large structural changes aren't possible.</p>
  
  <p>Even if I could just get a list of the properties in the extension, I'd be golden. I'd hack it up like this:</p>
  
  <pre><code>extend DataObj {
    optional SomeOtherBaseObj generic_extension = 100;
    optional bool generic_extension_type__SomeOtherBaseObj = 101;
  }
  </code></pre>
  
  <p>The generic_extension_type__... would be there for no reason, other than to give me the name of the type for generic_extension. Though, if I could do that, I could simplify that to:</p>
  
  <pre><code>extend DataObj {
    optional SomeOtherBaseObj generic_extension__SomeOtherBaseObj = 100;
  }
  </code></pre>