def FieldpathNature(fieldpath, protobuf=None): """Returns information about the nature of a given field. Args: fieldpath: path of the field of interest protobuf: container of the field. Returns: tuple of: (whether <fieldpath> is contained in the protobuf, is true-or-honorary primitive, is strictly honorary primitive) """ if protobuf is None: protobuf = StructuralDbroot() toks = path_utils.SplitAbstract(path_utils.AsAbstract(fieldpath)) fname, rest = path_utils.FirstRest(toks) fd = protobuf.DESCRIPTOR.fields_by_name.get(fname, None) if fd is None: return (False, None, None) while bool(rest) and fd.type == fd.TYPE_MESSAGE: fname, rest = path_utils.FirstRest(rest) fd = fd.message_type.fields_by_name.get(fname, None) if fd is None: # path contains something not in the protobuf return (False, None, None) # 'poked through the bottom' of the protobuf if rest: return (False, None, None) is_true_primitive = fd.type != fd.TYPE_MESSAGE is_primitive_like = is_true_primitive or ( path_converters.IsHonoraryPrimitive(fd.message_type.name)) return (True, is_primitive_like, not is_true_primitive)
def _IsFieldPathPrimitiveLike(fieldpath, protobuf): """Whether fieldpath is an actual primitive, or honorary primitive. We allow this latter, for our doc writers, so they don't have to fiddle + maybe get wrong, adding :value to the end of so much. Args: fieldpath: path to field. protobuf: protobuf in which to find field. Returns: whether the field at fieldpath is a primitive (true leaf) or, an honorary primitive. """ toks = path_utils.SplitAbstract(path_utils.AsAbstract(fieldpath)) fname, rest = path_utils.FirstRest(toks) fd = protobuf.DESCRIPTOR.fields_by_name.get(fname, None) if fd is None: return False while bool(rest) and fd.type == fd.TYPE_MESSAGE: fname, rest = path_utils.FirstRest(rest) fd = fd.message_type.fields_by_name.get(fname, None) if fd is None: # path contains something not in the protobuf return False # Ended of path return (not rest) and ( # .. is primitive fd.type != fd.TYPE_MESSAGE or # .. or honorary primitive path_converters.IsHonoraryPrimitive(fd.message_type.name))
def _IsFieldPathPrimitive(fieldpath, protobuf): """Whether the fieldpath is a (true) leaf in protobuf. whether protobuf structurally contains the path and, that it ends at a primitive (ie rejects subtree paths). Args: fieldpath: path of the field within the protobuf protobuf: container of the protobuf Returns: whether the fieldpath ends at a true leaf ie, value field. """ toks = path_utils.SplitAbstract(path_utils.AsAbstract(fieldpath)) fname, rest = path_utils.FirstRest(toks) fd = protobuf.DESCRIPTOR.fields_by_name.get(fname, None) if fd is None: return False while bool(rest) and fd.type == fd.TYPE_MESSAGE: fname, rest = path_utils.FirstRest(rest) fd = fd.message_type.fields_by_name.get(fname, None) if fd is None: # path contains something not in the protobuf return False # Both ended on a primitive. return (not rest) and (fd.type != fd.TYPE_MESSAGE)
def _MassageSpecialCases(almost_snippet_values, log): """Catchall for converting anything fiddled-with back to pure dbroot form. Right now just translates enum text to numeric values. Args: almost_snippet_values: snippet values. log: logger obj. Returns: All the snippet values, ready to write to a dbroot. """ log.debug(">massaging...") true_snippet_values = [] assert isinstance(almost_snippet_values, list) log.debug("survived assertion") dbroot_proto_for_structure = dbroot_utils.MakeEmptyDbroot() for concrete_fieldpath, snippet_value in almost_snippet_values: log.debug("concrete for no good reason " + concrete_fieldpath) abstract_fieldpath = path_utils.AsAbstract(concrete_fieldpath) log.debug("abs field:" + abstract_fieldpath) fdesc = proto_reflection.FieldDescriptorAtFieldPath( dbroot_proto_for_structure, abstract_fieldpath) log.debug("got field desc") is_enum = fdesc.enum_type is not None log.debug("enum? " + str(is_enum)) # Special case - on the client we represent /repeated enums/ as a choice of # fixed checkboxes. Here, we convert that back. if not is_enum: # plain log.debug("massaging, but plain: " + concrete_fieldpath + " " + str(snippet_value)) true_snippet_values.append((concrete_fieldpath, snippet_value)) log.debug("did not massage non-enum") else: is_repeated = fdesc.label == fdesc.LABEL_REPEATED if not is_repeated: log.debug("massaging singular enum:" + concrete_fieldpath + snippet_value) enum_val = _EnumValFromText(fdesc, snippet_value, log) log.debug("massaged singular; " + concrete_fieldpath + " " + str(enum_val)) true_snippet_values.append((concrete_fieldpath, enum_val)) else: # repeated enum log.debug("supposedly repeated enum...name: %s %s" % (concrete_fieldpath, str(snippet_value))) enum_text_vals = _ExtractWidgetEnumTextValues( snippet_value, log) for i, enum_text in enumerate(enum_text_vals): log.debug("enum text: " + enum_text) log.debug("all enum vals: " + fdesc.name) log.debug("all enum vals: " + str(fdesc.enum_type.values_by_name.keys())) enum_val = _EnumValFromText(fdesc, enum_text, log) log.debug("whew, found enum val!") # need to concretize, now! No way around it. log.debug("special enum snippetval: " + snippet_value + "->" + str(enum_val)) # thank heaven these can only be primitives! (& thus easy to get at) added_concrete_fieldpath = concrete_fieldpath + "[%d]" % i log.debug("enummed: " + added_concrete_fieldpath) true_snippet_values.append( (added_concrete_fieldpath, enum_val)) log.debug("massaged enum") log.debug("done massaging") return true_snippet_values