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

Commit 38a3f5e2 authored by Stefan Lafon's avatar Stefan Lafon Committed by Android (Google) Code Review
Browse files

Merge "Generate constants for enum values."

parents ae74e89e 9478f351
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
namespace android {
namespace stats_log_api_gen {

using google::protobuf::EnumDescriptor;
using google::protobuf::FieldDescriptor;
using google::protobuf::FileDescriptor;
using google::protobuf::SourceLocation;
@@ -120,7 +121,7 @@ java_type(const FieldDescriptor* field)
        case FieldDescriptor::TYPE_UINT32:
            return JAVA_TYPE_INT;
        case FieldDescriptor::TYPE_ENUM:
            return JAVA_TYPE_INT;
            return JAVA_TYPE_ENUM;
        case FieldDescriptor::TYPE_SFIXED32:
            return JAVA_TYPE_INT;
        case FieldDescriptor::TYPE_SFIXED64:
@@ -208,7 +209,6 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)
                errorCount++;
                continue;
            }

        }

        // Check that if there's a WorkSource, it's at position 1.
@@ -228,16 +228,27 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)

        AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());

        // Build the type signature
        // Build the type signature and the atom data.
        vector<java_type_t> signature;
        for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin();
                it != fields.end(); it++) {
            const FieldDescriptor* field = it->second;
            java_type_t javaType = java_type(field);

            atomDecl.fields.push_back(AtomField(field->name(), javaType));
            AtomField atField(field->name(), javaType);
            if (javaType == JAVA_TYPE_ENUM) {
                // All enums are treated as ints when it comes to function signatures.
                signature.push_back(JAVA_TYPE_INT);
                const EnumDescriptor* enumDescriptor = field->enum_type();
                for (int i = 0; i < enumDescriptor->value_count(); i++) {
                    atField.enumValues[enumDescriptor->value(i)->number()] =
                        enumDescriptor->value(i)->name().c_str();
                }
            } else {
                signature.push_back(javaType);
            }
            atomDecl.fields.push_back(atField);
        }

        atoms->signatures.insert(signature);
        atoms->decls.insert(atomDecl);
@@ -261,5 +272,3 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)

}  // namespace stats_log_api_gen
}  // namespace android

+9 −1
Original line number Diff line number Diff line
@@ -22,10 +22,12 @@

#include <set>
#include <vector>
#include <map>

namespace android {
namespace stats_log_api_gen {

using std::map;
using std::set;
using std::string;
using std::vector;
@@ -44,6 +46,7 @@ typedef enum {
    JAVA_TYPE_FLOAT = 5,
    JAVA_TYPE_DOUBLE = 6,
    JAVA_TYPE_STRING = 7,
    JAVA_TYPE_ENUM = 8,

    JAVA_TYPE_OBJECT = -1,
    JAVA_TYPE_BYTE_ARRAY = -2,
@@ -57,8 +60,13 @@ struct AtomField {
    string name;
    java_type_t javaType;

    // If the field is of type enum, the following map contains the list of enum values.
    map<int /* numeric value */, string /* value name */> enumValues;

    inline AtomField() :name(), javaType(JAVA_TYPE_UNKNOWN) {}
    inline AtomField(const AtomField& that) :name(that.name), javaType(that.javaType) {}
    inline AtomField(const AtomField& that) :name(that.name),
                                             javaType(that.javaType),
                                             enumValues(that.enumValues) {}
    inline AtomField(string n, java_type_t jt) :name(n), javaType(jt) {}
    inline ~AtomField() {}
};
+29 −3
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ cpp_type_name(java_type_t type)
        case JAVA_TYPE_BOOLEAN:
            return "bool";
        case JAVA_TYPE_INT:
        case JAVA_TYPE_ENUM:
            return "int32_t";
        case JAVA_TYPE_LONG:
            return "int64_t";
@@ -77,6 +78,7 @@ java_type_name(java_type_t type)
        case JAVA_TYPE_BOOLEAN:
            return "boolean";
        case JAVA_TYPE_INT:
        case JAVA_TYPE_ENUM:
            return "int";
        case JAVA_TYPE_LONG:
            return "long";
@@ -173,7 +175,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms)
    fprintf(out, " */\n");
    fprintf(out, "\n");
    fprintf(out, "/**\n");
    fprintf(out, " * Constants for event codes.\n");
    fprintf(out, " * Constants for atom codes.\n");
    fprintf(out, " */\n");
    fprintf(out, "enum {\n");

@@ -240,9 +242,9 @@ write_stats_log_java(FILE* out, const Atoms& atoms)
    fprintf(out, " * @hide\n");
    fprintf(out, " */\n");
    fprintf(out, "public final class StatsLog {\n");
    fprintf(out, "    // Constants for event codes.\n");
    fprintf(out, "    // Constants for atom codes.\n");

    // Print constants
    // Print constants for the atom codes.
    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
            atom != atoms.decls.end(); atom++) {
        string constant = make_constant_name(atom->name);
@@ -260,6 +262,27 @@ write_stats_log_java(FILE* out, const Atoms& atoms)
    }
    fprintf(out, "\n");

    // Print constants for the enum values.
    fprintf(out, "    // Constants for enum values.\n\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++) {
          if (field->javaType == JAVA_TYPE_ENUM) {
            fprintf(out, "    // Values for %s.%s\n", atom->message.c_str(), field->name.c_str());
            for (map<int, string>::const_iterator value = field->enumValues.begin();
                 value != field->enumValues.end(); value++) {
              fprintf(out, "    public static final int %s__%s__%s = %d;\n",
                      make_constant_name(atom->message).c_str(),
                      make_constant_name(field->name).c_str(),
                      make_constant_name(value->second).c_str(),
                      value->first);
            }
            fprintf(out, "\n");
          }
        }
    }

    // Print write methods
    fprintf(out, "    // Write methods\n");
    for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin();
@@ -286,6 +309,7 @@ jni_type_name(java_type_t type)
        case JAVA_TYPE_BOOLEAN:
            return "jboolean";
        case JAVA_TYPE_INT:
        case JAVA_TYPE_ENUM:
            return "jint";
        case JAVA_TYPE_LONG:
            return "jlong";
@@ -311,6 +335,7 @@ jni_function_name(const vector<java_type_t>& signature)
                result += "_boolean";
                break;
            case JAVA_TYPE_INT:
            case JAVA_TYPE_ENUM:
                result += "_int";
                break;
            case JAVA_TYPE_LONG:
@@ -340,6 +365,7 @@ java_type_signature(java_type_t type)
        case JAVA_TYPE_BOOLEAN:
            return "Z";
        case JAVA_TYPE_INT:
        case JAVA_TYPE_ENUM:
            return "I";
        case JAVA_TYPE_LONG:
            return "J";
+32 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
namespace android {
namespace stats_log_api_gen {

using std::map;
using std::set;
using std::vector;

@@ -54,6 +55,29 @@ set_contains_vector(const set<vector<java_type_t>>& s, int count, ...)
        EXPECT_TRUE(set_contains_vector(s, count, __VA_ARGS__)); \
    } while(0)

/** Expects that the provided atom has no enum values for any field. */
#define EXPECT_NO_ENUM_FIELD(atom) \
    do { \
        for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
             field != atom->fields.end(); field++) { \
            EXPECT_TRUE(field->enumValues.empty()); \
        } \
    } while(0)

/** Expects that exactly one specific field has expected enum values. */ 
#define EXPECT_HAS_ENUM_FIELD(atom, field_name, values)        \
    do { \
        for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
             field != atom->fields.end(); field++) { \
            if (field->name == field_name) { \
                EXPECT_EQ(field->enumValues, values); \
            } else { \
                EXPECT_TRUE(field->enumValues.empty()); \
            } \
        } \
    } while(0)


/**
 * Test a correct collation, with all the types.
 */
@@ -94,21 +118,28 @@ TEST(CollationTest, CollateStats) {
    EXPECT_EQ(1, atom->code);
    EXPECT_EQ("int_atom", atom->name);
    EXPECT_EQ("IntAtom", atom->message);
    EXPECT_NO_ENUM_FIELD(atom);
    atom++;

    EXPECT_EQ(2, atom->code);
    EXPECT_EQ("out_of_order_atom", atom->name);
    EXPECT_EQ("OutOfOrderAtom", atom->message);
    EXPECT_NO_ENUM_FIELD(atom);
    atom++;

    EXPECT_EQ(3, atom->code);
    EXPECT_EQ("another_int_atom", atom->name);
    EXPECT_EQ("AnotherIntAtom", atom->message);
    EXPECT_NO_ENUM_FIELD(atom);
    atom++;

    EXPECT_EQ(4, atom->code);
    EXPECT_EQ("all_types_atom", atom->name);
    EXPECT_EQ("AllTypesAtom", atom->message);
    map<int, string> enumValues;
    enumValues[0] = "VALUE0";
    enumValues[1] = "VALUE1";
    EXPECT_HAS_ENUM_FIELD(atom, "enum_field", enumValues);
    atom++;

    EXPECT_TRUE(atom == atoms.decls.end());
@@ -125,7 +156,7 @@ TEST(CollationTest, NonMessageTypeFails) {
}

/**
 * Test that atoms that have non-primitve types are rejected.
 * Test that atoms that have non-primitive types are rejected.
 */
TEST(CollationTest, FailOnBadTypes) {
    Atoms atoms;
@@ -165,7 +196,5 @@ TEST(CollationTest, FailBadWorkSourcePosition) {
    EXPECT_EQ(1, errorCount);
}


}  // namespace stats_log_api_gen
}  // namespace android