Esempio 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))
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
0
def _GeneralSetAbstract(parts, value, store, log):
    """Set a value in store, where the top level of store is not repeated.

  It complements _SetAbstractThroughRepeated.

  Args:
      parts: already-broken-up path, of where to put the value.
      value: value to write into the store.
      store: the multi-level dict to write into.
      log: logger object
  """
    assert isinstance(store, dict)
    key, rest = path_utils.FirstRest(parts)
    # not concrete
    assert not key.isdigit()
    if not rest:
        store[key] = value
    else:
        substore = store.get(key, {})
        if not substore:
            store[key] = substore

        if isinstance(substore, dict):
            if substore and substore.keys()[0].isdigit():
                # Handle repeated elements.
                _SetAbstractThroughRepeated(rest, value, substore, log)
            else:
                # Get the next element from path to check if it is index of repeated
                # element.
                next_key, unused_rest = path_utils.FirstRest(rest)
                if next_key and next_key == "[]":
                    # Handle repeated elements. It is the case when there is no items of
                    # repeated element, and first field is coming to set.
                    _SetAbstractThroughRepeated(rest, value, substore, log)
                else:
                    # Handle generic elements.
                    _GeneralSetAbstract(rest, value, substore, log)

        else:
            # It breaks an invariant of the protobuf => sparse tree, to replace
            # a primitive value with a subtree. Eg, trying to write
            # 'a.b' = 2 to {'a': 1}. 'b' cannot be a sibling of 2. That would be
            # the error we're trying to do here.
            log.error(
                "Programmer or data error; cannot write a subtree (%s) over"
                " a primitive value (%s); that\'s an invariant of protobufs =>"
                " sparse trees. Value ignored, but no further damage done. "
                "%s" % (str(key), str(store), repr(traceback.extract_stack())))
Esempio n. 5
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)
Esempio n. 6
0
 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