Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6c38632 authored by Muhammad Qureshi's avatar Muhammad Qureshi
Browse files

Group annotations for the same atom id

Group annotations for the same atom id inside one if-block in generated
code.

Use shared_ptr to store AtomDecls in multiple data structures.

Store a mapping of field numbers to atoms that have annotations at
corresponding field numbers in Collation.h

Bug: 151744250
Test: stats-log-api-gen-test
Test: m stats-log-api-gen
Test: m libstatsmetadata
Test: m statslog-framework-java-gen
Test: m libstatslog

Change-Id: I874696cfb5c27141017b4293bec809ab510ceb98
parent 52f4d8d9
Loading
Loading
Loading
Loading
+26 −26
Original line number Diff line number Diff line
@@ -454,16 +454,12 @@ bool get_non_chained_node(const Descriptor* atom, AtomDecl* atomDecl,
    return has_attribution_node;
}

static void populateFieldNumberToAnnotations(const AtomDecl& atomDecl,
                                             FieldNumberToAnnotations* fieldNumberToAnnotations) {
    for (FieldNumberToAnnotations::const_iterator it = atomDecl.fieldNumberToAnnotations.begin();
         it != atomDecl.fieldNumberToAnnotations.end(); it++) {
static void populateFieldNumberToAtomDeclSet(const shared_ptr<AtomDecl>& atomDecl,
                                             FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet) {
    for (FieldNumberToAnnotations::const_iterator it = atomDecl->fieldNumberToAnnotations.begin();
         it != atomDecl->fieldNumberToAnnotations.end(); it++) {
        const int fieldNumber = it->first;
        const set<shared_ptr<Annotation>>& insertAnnotationsSource = it->second;
        set<shared_ptr<Annotation>>& insertAnnotationsTarget =
                (*fieldNumberToAnnotations)[fieldNumber];
        insertAnnotationsTarget.insert(insertAnnotationsSource.begin(),
                                       insertAnnotationsSource.end());
        (*fieldNumberToAtomDeclSet)[fieldNumber].insert(atomDecl);
    }
}

@@ -513,18 +509,19 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
        }

        const Descriptor* atom = atomField->message_type();
        AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
        shared_ptr<AtomDecl> atomDecl =
                make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());

        if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
            atomDecl.whitelisted = true;
            atomDecl->whitelisted = true;
            if (dbg) {
                printf("%s is whitelisted\n", atomField->name().c_str());
            }
        }

        if (atomDecl.code < PULL_ATOM_START_ID &&
        if (atomDecl->code < PULL_ATOM_START_ID &&
            atomField->options().GetExtension(os::statsd::truncate_timestamp)) {
            addAnnotationToAtomDecl(&atomDecl, ATOM_ID_FIELD_NUMBER,
            addAnnotationToAtomDecl(atomDecl.get(), ATOM_ID_FIELD_NUMBER,
                                    ANNOTATION_ID_TRUNCATE_TIMESTAMP, ANNOTATION_TYPE_BOOL,
                                    AnnotationValue(true));
            if (dbg) {
@@ -533,29 +530,33 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
        }

        vector<java_type_t> signature;
        errorCount += collate_atom(atom, &atomDecl, &signature);
        if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) {
        errorCount += collate_atom(atom, atomDecl.get(), &signature);
        if (atomDecl->primaryFields.size() != 0 && atomDecl->exclusiveField == 0) {
            print_error(atomField, "Cannot have a primary field without an exclusive field: %s\n",
                        atomField->name().c_str());
            errorCount++;
            continue;
        }

        FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = atoms->signatureInfoMap[signature];
        populateFieldNumberToAtomDeclSet(atomDecl, &fieldNumberToAtomDeclSet);

        atoms->decls.insert(atomDecl);
        FieldNumberToAnnotations& fieldNumberToAnnotations = atoms->signatureInfoMap[signature];
        populateFieldNumberToAnnotations(atomDecl, &fieldNumberToAnnotations);

        AtomDecl nonChainedAtomDecl(atomField->number(), atomField->name(), atom->name());
        shared_ptr<AtomDecl> nonChainedAtomDecl =
                make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());
        vector<java_type_t> nonChainedSignature;
        if (get_non_chained_node(atom, &nonChainedAtomDecl, &nonChainedSignature)) {
            atoms->non_chained_decls.insert(nonChainedAtomDecl);
            FieldNumberToAnnotations& fieldNumberToAnnotations =
        if (get_non_chained_node(atom, nonChainedAtomDecl.get(), &nonChainedSignature)) {
            FieldNumberToAtomDeclSet& nonChainedFieldNumberToAtomDeclSet =
                    atoms->nonChainedSignatureInfoMap[nonChainedSignature];
            populateFieldNumberToAnnotations(atomDecl, &fieldNumberToAnnotations);
            populateFieldNumberToAtomDeclSet(nonChainedAtomDecl,
                                             &nonChainedFieldNumberToAtomDeclSet);

            atoms->non_chained_decls.insert(nonChainedAtomDecl);
        }

        if (atomDecl.code < PULL_ATOM_START_ID && atomDecl.code > maxPushedAtomId) {
            maxPushedAtomId = atomDecl.code;
        if (atomDecl->code < PULL_ATOM_START_ID && atomDecl->code > maxPushedAtomId) {
            maxPushedAtomId = atomDecl->code;
        }
    }

@@ -563,8 +564,7 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*

    if (dbg) {
        printf("signatures = [\n");
        for (map<vector<java_type_t>, FieldNumberToAnnotations>::const_iterator it =
                     atoms->signatureInfoMap.begin();
        for (SignatureInfoMap::const_iterator it = atoms->signatureInfoMap.begin();
             it != atoms->signatureInfoMap.end(); it++) {
            printf("   ");
            for (vector<java_type_t>::const_iterator jt = it->first.begin(); jt != it->first.end();
+22 −5
Original line number Diff line number Diff line
@@ -110,7 +110,16 @@ struct Annotation {
    }
};

using FieldNumberToAnnotations = map<int, set<shared_ptr<Annotation>>>;
struct SharedComparator {
    template <typename T>
    inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const {
        return (*lhs) < (*rhs);
    }
};

using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>;

using FieldNumberToAnnotations = map<int, AnnotationSet>;

/**
 * The name and type for an atom field.
@@ -169,11 +178,19 @@ struct AtomDecl {
    }
};

using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>;

// Maps a field number to a set of atoms that have annotation(s) for their field with that field
// number.
using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>;

using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>;

struct Atoms {
    map<vector<java_type_t>, FieldNumberToAnnotations> signatureInfoMap;
    set<AtomDecl> decls;
    set<AtomDecl> non_chained_decls;
    map<vector<java_type_t>, FieldNumberToAnnotations> nonChainedSignatureInfoMap;
    SignatureInfoMap signatureInfoMap;
    AtomDeclSet decls;
    AtomDeclSet non_chained_decls;
    SignatureInfoMap nonChainedSignatureInfoMap;
    int maxPushedAtomId;
};

+36 −36
Original line number Diff line number Diff line
@@ -62,11 +62,11 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) {
    fprintf(out,
            "const std::set<int> "
            "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n");
    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end();
         atom++) {
        if (kTruncatingAtomNames.find(atom->name) != kTruncatingAtomNames.end()) {
            const string constant = make_constant_name(atom->name);
            fprintf(out, "    %d, // %s\n", atom->code, constant.c_str());
    for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
         atomIt++) {
        if (kTruncatingAtomNames.find((*atomIt)->name) != kTruncatingAtomNames.end()) {
            const string constant = make_constant_name((*atomIt)->name);
            fprintf(out, "    %d, // %s\n", (*atomIt)->code, constant.c_str());
        }
    }

@@ -74,13 +74,13 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) {
    fprintf(out, "\n");

    fprintf(out, "const std::set<int> AtomsInfo::kAtomsWithAttributionChain = {\n");
    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end();
         atom++) {
        for (vector<AtomField>::const_iterator field = atom->fields.begin();
             field != atom->fields.end(); field++) {
    for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
         atomIt++) {
        for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin();
             field != (*atomIt)->fields.end(); field++) {
            if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                const string constant = make_constant_name(atom->name);
                fprintf(out, "    %d, // %s\n", atom->code, constant.c_str());
                const string constant = make_constant_name((*atomIt)->name);
                fprintf(out, "    %d, // %s\n", (*atomIt)->code, constant.c_str());
                break;
            }
        }
@@ -90,11 +90,11 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) {
    fprintf(out, "\n");

    fprintf(out, "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n");
    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end();
         atom++) {
        if (atom->whitelisted) {
            const string constant = make_constant_name(atom->name);
            fprintf(out, "    %d, // %s\n", atom->code, constant.c_str());
    for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
         atomIt++) {
        if ((*atomIt)->whitelisted) {
            const string constant = make_constant_name((*atomIt)->name);
            fprintf(out, "    %d, // %s\n", (*atomIt)->code, constant.c_str());
        }
    }

@@ -103,17 +103,17 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) {

    fprintf(out, "static std::map<int, int> getAtomUidField() {\n");
    fprintf(out, "    std::map<int, int> uidField;\n");
    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end();
         atom++) {
        if (atom->uidField == 0) {
    for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
         atomIt++) {
        if ((*atomIt)->uidField == 0) {
            continue;
        }
        fprintf(out,
                "\n    // Adding uid field for atom "
                "(%d)%s\n",
                atom->code, atom->name.c_str());
        fprintf(out, "    uidField[%d /* %s */] = %d;\n", atom->code,
                make_constant_name(atom->name).c_str(), atom->uidField);
                (*atomIt)->code, (*atomIt)->name.c_str());
        fprintf(out, "    uidField[%d /* %s */] = %d;\n", (*atomIt)->code,
                make_constant_name((*atomIt)->name).c_str(), (*atomIt)->uidField);
    }

    fprintf(out, "    return uidField;\n");
@@ -128,35 +128,35 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) {
            "getStateAtomFieldOptions() {\n");
    fprintf(out, "    std::map<int, StateAtomFieldOptions> options;\n");
    fprintf(out, "    StateAtomFieldOptions* opt;\n");
    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end();
         atom++) {
        if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) {
    for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
         atomIt++) {
        if ((*atomIt)->primaryFields.size() == 0 && (*atomIt)->exclusiveField == 0) {
            continue;
        }
        fprintf(out,
                "\n    // Adding primary and exclusive fields for atom "
                "(%d)%s\n",
                atom->code, atom->name.c_str());
        fprintf(out, "    opt = &(options[%d /* %s */]);\n", atom->code,
                make_constant_name(atom->name).c_str());
        fprintf(out, "    opt->primaryFields.reserve(%lu);\n", atom->primaryFields.size());
        for (const auto& field : atom->primaryFields) {
                (*atomIt)->code, (*atomIt)->name.c_str());
        fprintf(out, "    opt = &(options[%d /* %s */]);\n", (*atomIt)->code,
                make_constant_name((*atomIt)->name).c_str());
        fprintf(out, "    opt->primaryFields.reserve(%lu);\n", (*atomIt)->primaryFields.size());
        for (const auto& field : (*atomIt)->primaryFields) {
            fprintf(out, "    opt->primaryFields.push_back(%d);\n", field);
        }

        fprintf(out, "    opt->exclusiveField = %d;\n", atom->exclusiveField);
        if (atom->defaultState != INT_MAX) {
            fprintf(out, "    opt->defaultState = %d;\n", atom->defaultState);
        fprintf(out, "    opt->exclusiveField = %d;\n", (*atomIt)->exclusiveField);
        if ((*atomIt)->defaultState != INT_MAX) {
            fprintf(out, "    opt->defaultState = %d;\n", (*atomIt)->defaultState);
        } else {
            fprintf(out, "    opt->defaultState = UNSET_VALUE;\n");
        }

        if (atom->resetState != INT_MAX) {
            fprintf(out, "    opt->resetState = %d;\n", atom->resetState);
        if ((*atomIt)->resetState != INT_MAX) {
            fprintf(out, "    opt->resetState = %d;\n", (*atomIt)->resetState);
        } else {
            fprintf(out, "    opt->resetState = UNSET_VALUE;\n");
        }
        fprintf(out, "    opt->nested = %d;\n", atom->nested);
        fprintf(out, "    opt->nested = %d;\n", (*atomIt)->nested);
    }

    fprintf(out, "    return options;\n");
+34 −32
Original line number Diff line number Diff line
@@ -22,8 +22,7 @@
namespace android {
namespace stats_log_api_gen {

static int write_java_q_logger_class(
        FILE* out, const map<vector<java_type_t>, FieldNumberToAnnotations>& signatureInfoMap,
static int write_java_q_logger_class(FILE* out, const SignatureInfoMap& signatureInfoMap,
                                     const AtomDecl& attributionDecl) {
    fprintf(out, "\n");
    fprintf(out, "    // Write logging helper methods for statsd in Q and earlier.\n");
@@ -41,20 +40,22 @@ static int write_java_q_logger_class(
}

static void write_annotations(FILE* out, int argIndex,
                              const FieldNumberToAnnotations& fieldNumberToAnnotations) {
    auto it = fieldNumberToAnnotations.find(argIndex);
    if (it == fieldNumberToAnnotations.end()) {
                              const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet) {
    FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
            fieldNumberToAtomDeclSet.find(argIndex);
    if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) {
        return;
    }
    const set<shared_ptr<Annotation>>& annotations = it->second;
    for (auto& annotation : annotations) {
        // TODO(b/151744250): Group annotations for same atoms.
    const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
    for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
        fprintf(out, "        if (code == %d) {\n", atomDecl->code);
        const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex);
        for (const shared_ptr<Annotation>& annotation : annotations) {
            // TODO(b/151786433): Write atom constant name instead of atom id literal.
        fprintf(out, "        if (code == %d) {\n", annotation->atomId);
            switch (annotation->type) {
            case ANNOTATION_TYPE_INT:
                // TODO(b/151776731): Check for reset state annotation and only include
                // reset state when field value == default state annotation value.
                case ANNOTATION_TYPE_INT:
                    // TODO(b/151786433): Write annotation constant name instead of
                    // annotation id literal.
                    fprintf(out, "            builder.addIntAnnotation((byte) %d, %d);\n",
@@ -64,24 +65,25 @@ static void write_annotations(FILE* out, int argIndex,
                    // TODO(b/151786433): Write annotation constant name instead of
                    // annotation id literal.
                    fprintf(out, "            builder.addBooleanAnnotation((byte) %d, %s);\n",
                        annotation->annotationId, annotation->value.boolValue ? "true" : "false");
                            annotation->annotationId,
                            annotation->value.boolValue ? "true" : "false");
                    break;
                default:
                    break;
            }
        }
        fprintf(out, "        }\n");
    }
}

static int write_java_methods(
        FILE* out, const map<vector<java_type_t>, FieldNumberToAnnotations>& signatureInfoMap,
static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
                              const AtomDecl& attributionDecl, const bool supportQ) {
    for (auto signatureInfoMapIt = signatureInfoMap.begin();
         signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
        // Print method signature.
        fprintf(out, "    public static void write(int code");
        const vector<java_type_t>& signature = signatureInfoMapIt->first;
        const FieldNumberToAnnotations& fieldNumberToAnnotations = signatureInfoMapIt->second;
        const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
        int argIndex = 1;
        for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
             arg++) {
@@ -120,7 +122,7 @@ static int write_java_methods(

        // Write atom code.
        fprintf(out, "%s        builder.setAtomId(code);\n", indent.c_str());
        write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAnnotations);
        write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet);

        // Write the args.
        argIndex = 1;
@@ -231,7 +233,7 @@ static int write_java_methods(
                    fprintf(stderr, "Encountered unsupported type.");
                    return 1;
            }
            write_annotations(out, argIndex, fieldNumberToAnnotations);
            write_annotations(out, argIndex, fieldNumberToAtomDeclSet);
            argIndex++;
        }

+2 −3
Original line number Diff line number Diff line
@@ -53,8 +53,7 @@ void write_java_q_logging_constants(FILE* out, const string& indent) {
    fprintf(out, "%sprivate static final int LIST_TYPE_OVERHEAD = 2;\n", indent.c_str());
}

int write_java_methods_q_schema(
        FILE* out, const map<vector<java_type_t>, FieldNumberToAnnotations>& signatureInfoMap,
int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap,
                                const AtomDecl& attributionDecl, const string& indent) {
    int requiredHelpers = 0;
    for (auto signatureInfoMapIt = signatureInfoMap.begin();
Loading