docs: def pb2json(pb, useFieldNumber=False):
      ''' convert google.protobuf.descriptor instance to JSON string '''
      js = {}
      # fields = pb.DESCRIPTOR.fields #all fields
      fields = pb.ListFields()        #only filled (including extensions)
      for field,value in fields:
          if useFieldNumber:
              key = field.number
          else:
              key = field.name
          if field.type == FD.TYPE_MESSAGE:
              ftype = partial(pb2json, useFieldNumber=useFieldNumber)
          elif field.type in _ftype2js:
              ftype = _ftype2js[field.type]
          else:
              raise ParseError("Field %s.%s of type '%d' is not supported" % (pb.__class__.__name__, field.name, field.type, ))
          if field.label == FD.LABEL_REPEATED:
              js_value = []
              for v in value:
                  js_value.append(ftype(v))
          else:
              js_value = ftype(value)
          js[key] = js_value
      return js