Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
def EmptyConcretizeFieldPath(fieldpath, protobuf=None):
    """Adds empty concreteness markings to an abstract fieldpath.

  Takes an abstract path (no indices or '[]') and puts '[]' markers at
  repeated parts, newstyle (ie a.b.[]). We do this for reading from
  the template, masking file.

  Args:
    fieldpath: path of the field within the protobuf
    protobuf: container of the protobuf
  Returns:
    fieldpath, with empty concrete markings.
  """
    assert path_utils.IsAbstract(fieldpath)
    if protobuf is None:
        protobuf = StructuralDbroot()
    toks = path_utils.SplitAbstract(fieldpath)
    empty_concrete_toks = []

    def AddElement(fname, fd):
        empty_concrete_toks.append(fname)
        if fd.label == fd.LABEL_REPEATED:
            empty_concrete_toks.append("[]")

    def GetNext(toks, fd):
        fname, rest = path_utils.FirstRest(toks)
        fd = fd.message_type.fields_by_name.get(fname, None)
        if fd is None:
            assert False, "bad path: %s, at: %s" % (fieldpath, fname)
        return fname, rest, fd

    fname, rest = path_utils.FirstRest(toks)
    fd = protobuf.DESCRIPTOR.fields_by_name.get(fname, None)
    if fd is None:
        assert False, "bad path: %s, at: %s" % (fieldpath, fname)

    AddElement(fname, fd)
    while bool(rest) and fd.type == fd.TYPE_MESSAGE:
        fname, rest, fd = GetNext(rest, fd)
        AddElement(fname, fd)

    assert (not rest) and (fd.type != fd.TYPE_MESSAGE), (
        "path %s incomplete or something" % fieldpath)
    return ".".join(empty_concrete_toks)