1. Implement Privacy Policy Tag Inheritance
2. Expose Dest values in IIncidentReportArgs.h

Please see bug for detail descriptions.

Bug: 67869340
Test: unit tested and on-device test. Ran command:
$ out/host/linux-x86/bin/incident-section-gen incidentd
to test various of privacy taggings.
Change-Id: I12af3d7da4c7c72bd63598893fe2c1f70b09baa4
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 674bee1..7650795 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -59,24 +59,31 @@
  *
  * #include "section_list.h"
  * ...
- * Privacy WindowState_state { 1, 9, NULL, LOCAL, NULL }; // first two integers are values for field id and proto type.
- * Privacy WindowState_child_windows { 3, 11, NULL, DEFAULT, NULL }; // reserved for WindowState_LIST
- * Privacy* WindowState_MSG_[] = {
+ * Privacy WindowState__state { 1, 9, NULL, LOCAL, NULL }; // first two integers are values for field id and proto type.
+ * Privacy WindowState__child_windows { 3, 11, NULL, UNSET, NULL }; // reserved for WindowState_LIST
+ * Privacy* WindowState__MSG__UNSET[] = {
  *     &WindowState_state,
  *     // display id is default, nothing is generated.
  *     &WindowState_child_windows,
  *     NULL  // terminator of the array
  * };
- * Privacy WindowState_my_window { 1, 11, WindowState_my_window_LIST, DEFAULT, NULL };
+ * Privacy WindowState__my_window { 1, 11, WindowState__MSG__UNSET, UNSET, NULL };
  *
  * createList() {
  *    ...
- *    WindowState_child_windows.children = WindowState_my_window_LIST; // point to its own definition after the list is defined.
+ *    WindowState_child_windows.children = WindowState__MSG_UNSET; // point to its own definition after the list is defined.
  *    ...
  * }
  *
  * const Privacy** PRIVACY_POLICY_LIST = createList();
  * const int PRIVACY_POLICY_COUNT = 1;
+ *
+ * Privacy Value Inheritance rules:
+ * 1. Both field and message can be tagged with DESTINATION: LOCAL(L), EXPLICIT(E), AUTOMATIC(A).
+ * 2. Primitives inherits containing message's tag unless defined explicitly.
+ * 3. Containing message's tag doesn't apply to message fields, even when unset (in this case, uses its default message tag).
+ * 4. Message field tag overrides its default message tag.
+ * 5. UNSET tag defaults to EXPLICIT.
  */
 
 // The assignments will be called when constructs PRIVACY_POLICY_LIST, has to be global variable
@@ -164,14 +171,13 @@
     return result;
 }
 
-static string getFieldName(const FieldDescriptor* field) {
-    return replaceAll(field->full_name(), '.', "__");
+static inline void printPrivacy(const string& name, const FieldDescriptor* field, const string& children,
+        const Destination dest, const string& patterns, const string& comments = "") {
+    printf("Privacy %s = { %d, %d, %s, %d, %s };%s\n", name.c_str(), field->number(), field->type(),
+        children.c_str(), dest, patterns.c_str(), comments.c_str());
 }
 
-static string getMessageTypeName(const Descriptor* descriptor) {
-    return replaceAll(descriptor->full_name(), '.', "_") + "_MSG_";
-}
-
+// Get Custom Options ================================================================================
 static inline SectionFlags getSectionFlags(const FieldDescriptor* field) {
     return field->options().GetExtension(section);
 }
@@ -180,24 +186,64 @@
     return field->options().GetExtension(privacy);
 }
 
-static inline bool isDefaultField(const FieldDescriptor* field) {
-    return getPrivacyFlags(field).dest() == PrivacyFlags::default_instance().dest();
+static inline PrivacyFlags getPrivacyFlags(const Descriptor* descriptor) {
+    return descriptor->options().GetExtension(msg_privacy);
 }
 
-static bool isDefaultMessageImpl(const Descriptor* descriptor, set<string>* parents) {
-    int N = descriptor->field_count();
+// Get Destinations ===================================================================================
+static inline Destination getMessageDest(const Descriptor* descriptor, const Destination overridden) {
+    return overridden != DEST_UNSET ? overridden : getPrivacyFlags(descriptor).dest();
+}
+
+// Returns field's own dest, when it is a message field, uses its message default tag if unset.
+static inline Destination getFieldDest(const FieldDescriptor* field) {
+    Destination fieldDest = getPrivacyFlags(field).dest();
+    return field->type() != FieldDescriptor::TYPE_MESSAGE ? fieldDest :
+            getMessageDest(field->message_type(), fieldDest);
+}
+
+// Get Names ===========================================================================================
+static inline string getFieldName(const FieldDescriptor* field) {
+    // replace . with double underscores to avoid name conflicts since fields use snake naming convention
+    return replaceAll(field->full_name(), '.', "__");
+}
+
+
+static inline string getMessageName(const Descriptor* descriptor, const Destination overridden) {
+    // replace . with one underscore since messages use camel naming convention
+    return replaceAll(descriptor->full_name(), '.', "_") + "__MSG__" +
+            to_string(getMessageDest(descriptor, overridden));
+}
+
+// IsDefault ============================================================================================
+// Returns true if a field is default. Default is defined as this field has same dest as its containing message.
+// For message fields, it only looks at its field tag and own default mesaage tag, doesn't recursively go deeper.
+static inline bool isDefaultField(const FieldDescriptor* field, const Destination containerDest) {
+    Destination fieldDest = getFieldDest(field);
+    if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
+        return fieldDest == containerDest || (fieldDest == DEST_UNSET);
+    } else {
+        return fieldDest == containerDest ||
+            (containerDest == DEST_UNSET && fieldDest == DEST_EXPLICIT) ||
+            (containerDest == DEST_EXPLICIT && fieldDest == DEST_UNSET);
+    }
+}
+
+static bool isDefaultMessageImpl(const Descriptor* descriptor, const Destination dest, set<string>* parents) {
+    const int N = descriptor->field_count();
+    const Destination messageDest = getMessageDest(descriptor, dest);
     parents->insert(descriptor->full_name());
     for (int i=0; i<N; ++i) {
         const FieldDescriptor* field = descriptor->field(i);
-        // look at if the current field is default or not, return false immediately
-        if (!isDefaultField(field)) return false;
-
+        const Destination fieldDest = getFieldDest(field);
+        // If current field is not default, return false immediately
+        if (!isDefaultField(field, messageDest)) return false;
         switch (field->type()) {
             case FieldDescriptor::TYPE_MESSAGE:
                 // if self recursion, don't go deep.
                 if (parents->find(field->message_type()->full_name()) != parents->end()) break;
                 // if is a default message, just continue
-                if (isDefaultMessageImpl(field->message_type(), parents)) break;
+                if (isDefaultMessageImpl(field->message_type(), fieldDest, parents)) break;
                 // sub message is not default, so this message is always not default
                 return false;
             case FieldDescriptor::TYPE_STRING:
@@ -210,106 +256,118 @@
     return true;
 }
 
-static bool isDefaultMessage(const Descriptor* descriptor) {
+// Recursively look at if this message is default, meaning all its fields and sub-messages
+// can be described by the same dest.
+static bool isDefaultMessage(const Descriptor* descriptor, const Destination dest) {
     set<string> parents;
-    return isDefaultMessageImpl(descriptor, &parents);
+    return isDefaultMessageImpl(descriptor, dest, &parents);
 }
 
-// This function is called for looking at privacy tags for a message type and recursively its sub-messages
-// It prints out each fields's privacy tags and a List of Privacy of the message itself (don't print default values)
-// Returns false if the descriptor doesn't have any non default privacy flags set, including its submessages
-static bool generatePrivacyFlags(const Descriptor* descriptor, map<string, bool> &msgNames, set<string>* parents) {
-    bool hasDefaultFlags[descriptor->field_count()];
+// ===============================================================================================================
+static bool numberInOrder(const FieldDescriptor* f1, const FieldDescriptor* f2) {
+    return f1->number() < f2->number();
+}
 
-    string messageTypeName = getMessageTypeName(descriptor);
-    // if the message is already defined, skip it.
-    if (msgNames.find(messageTypeName) != msgNames.end()) {
-        bool hasDefault = msgNames[messageTypeName];
-        return !hasDefault; // don't generate if it has default privacy.
+// field numbers are possibly out of order, sort them here.
+static vector<const FieldDescriptor*> sortFields(const Descriptor* descriptor) {
+    vector<const FieldDescriptor*> fields;
+    fields.reserve(descriptor->field_count());
+    for (int i=0; i<descriptor->field_count(); i++) {
+        fields.push_back(descriptor->field(i));
+    }
+    std::sort(fields.begin(), fields.end(), numberInOrder);
+    return fields;
+}
+
+// This function looks for privacy tags of a message type and recursively its sub-messages.
+// It generates Privacy objects for each non-default fields including non-default sub-messages.
+// And if the message has Privacy objects generated, it returns a list of them.
+// Returns false if the descriptor doesn't have any non default privacy flags set, including its submessages
+static bool generatePrivacyFlags(const Descriptor* descriptor, const Destination overridden,
+        map<string, bool> &variableNames, set<string>* parents) {
+    const string messageName = getMessageName(descriptor, overridden);
+    const Destination messageDest = getMessageDest(descriptor, overridden);
+
+    if (variableNames.find(messageName) != variableNames.end()) {
+        bool hasDefault = variableNames[messageName];
+        return !hasDefault; // if has default, then don't generate privacy flags.
     }
     // insert the message type name so sub-message will figure out if self-recursion occurs
-    parents->insert(messageTypeName);
+    parents->insert(messageName);
 
-    // iterate though its field and generate sub flags first
-    for (int i=0; i<descriptor->field_count(); i++) {
-        hasDefaultFlags[i] = true; // set default to true
-
-        const FieldDescriptor* field = descriptor->field(i);
+    // sort fields based on number, iterate though them and generate sub flags first
+    vector<const FieldDescriptor*> fieldsInOrder = sortFields(descriptor);
+    bool hasDefaultFlags[fieldsInOrder.size()];
+    for (size_t i=0; i<fieldsInOrder.size(); i++) {
+        const FieldDescriptor* field = fieldsInOrder[i];
         const string fieldName = getFieldName(field);
-        // check if the same field name is already defined.
-        if (msgNames.find(fieldName) != msgNames.end()) {
-            hasDefaultFlags[i] = msgNames[fieldName];
-            continue;
-        };
+        const Destination fieldDest = getFieldDest(field);
 
-        PrivacyFlags p = getPrivacyFlags(field);
+        if (variableNames.find(fieldName) != variableNames.end()) {
+            hasDefaultFlags[i] = variableNames[fieldName];
+            continue;
+        }
+        hasDefaultFlags[i] = isDefaultField(field, messageDest);
+
         string fieldMessageName;
+        PrivacyFlags p = getPrivacyFlags(field);
         switch (field->type()) {
             case FieldDescriptor::TYPE_MESSAGE:
-                fieldMessageName = getMessageTypeName(field->message_type());
+                fieldMessageName = getMessageName(field->message_type(), fieldDest);
                 if (parents->find(fieldMessageName) != parents->end()) { // Self-Recursion proto definition
-                    if (isDefaultField(field)) {
-                        hasDefaultFlags[i] = isDefaultMessage(field->message_type());
-                    } else {
-                        hasDefaultFlags[i] = false;
+                    if (hasDefaultFlags[i]) {
+                        hasDefaultFlags[i] = isDefaultMessage(field->message_type(), fieldDest);
                     }
                     if (!hasDefaultFlags[i]) {
-                        printf("Privacy %s = { %d, %d, NULL, %d, NULL }; // self recursion field of %s\n",
-                                fieldName.c_str(), field->number(), field->type(), p.dest(), fieldMessageName.c_str());
+                        printPrivacy(fieldName, field, "NULL", fieldDest, "NULL",
+                            " // self recursion field of " + fieldMessageName);
                         // generate the assignment and used to construct createList function later on.
                         gSelfRecursionAssignments.push_back(fieldName + ".children = " + fieldMessageName);
                     }
-                    break;
-                } else if (generatePrivacyFlags(field->message_type(), msgNames, parents)) {
-                    printf("Privacy %s = { %d, %d, %s, %d, NULL };\n", fieldName.c_str(), field->number(),
-                            field->type(), fieldMessageName.c_str(), p.dest());
-                } else if (isDefaultField(field)) {
-                    // don't create a new privacy if the value is default.
-                    break;
-                } else {
-                    printf("Privacy %s = { %d, %d, NULL, %d, NULL };\n", fieldName.c_str(), field->number(),
-                            field->type(), p.dest());
+                } else if (generatePrivacyFlags(field->message_type(), p.dest(), variableNames, parents)) {
+                    if (variableNames.find(fieldName) == variableNames.end()) {
+                        printPrivacy(fieldName, field, fieldMessageName, fieldDest, "NULL");
+                    }
+                    hasDefaultFlags[i] = false;
+                } else if (!hasDefaultFlags[i]) {
+                    printPrivacy(fieldName, field, "NULL", fieldDest, "NULL");
                 }
-                hasDefaultFlags[i] = false;
                 break;
             case FieldDescriptor::TYPE_STRING:
-                if (isDefaultField(field) && p.patterns_size() == 0) break;
-
-                printf("const char* %s_patterns[] = {\n", fieldName.c_str());
-                for (int i=0; i<p.patterns_size(); i++) {
-                    // the generated string need to escape backslash as well, need to dup it here
-                    printf("    \"%s\",\n", replaceAll(p.patterns(i), '\\', "\\\\").c_str());
+                if (p.patterns_size() != 0) { // if patterns are specified
+                    if (hasDefaultFlags[i]) break;
+                    printf("const char* %s_patterns[] = {\n", fieldName.c_str());
+                    for (int j=0; j<p.patterns_size(); j++) {
+                        // generated string needs to escape backslash too, duplicate it to allow escape again.
+                        printf("    \"%s\",\n", replaceAll(p.patterns(j), '\\', "\\\\").c_str());
+                    }
+                    printf("    NULL };\n");
+                    printPrivacy(fieldName, field, "NULL", fieldDest, fieldName + "_patterns");
+                    break;
                 }
-                printf("    NULL };\n");
-                printf("Privacy %s = { %d, %d, NULL, %d, %s_patterns };\n", fieldName.c_str(), field->number(),
-                        field->type(), p.dest(), fieldName.c_str());
-                hasDefaultFlags[i] = false;
-                break;
+                // else treat string field as primitive field and goes to default
             default:
-                if (isDefaultField(field)) break;
-                printf("Privacy %s = { %d, %d, NULL, %d, NULL };\n", fieldName.c_str(), field->number(),
-                        field->type(), p.dest());
-                hasDefaultFlags[i] = false;
+                if (!hasDefaultFlags[i]) printPrivacy(fieldName, field, "NULL", fieldDest, "NULL");
         }
-        // add the field name to message map, true means it has default flags
-        msgNames[fieldName] = hasDefaultFlags[i];
+        // Don't generate a variable twice
+        if (!hasDefaultFlags[i]) variableNames[fieldName] = false;
     }
 
     bool allDefaults = true;
-    for (int i=0; i<descriptor->field_count(); i++) {
+    for (size_t i=0; i<fieldsInOrder.size(); i++) {
         allDefaults &= hasDefaultFlags[i];
     }
 
-    parents->erase(messageTypeName); // erase the message type name when exit the message.
-    msgNames[messageTypeName] = allDefaults; // store the privacy tags of the message here to avoid overhead.
+    parents->erase(messageName); // erase the message type name when exit the message.
+    variableNames[messageName] = allDefaults; // store the privacy tags of the message here to avoid overhead.
 
     if (allDefaults) return false;
 
     emptyline();
     int policyCount = 0;
-    printf("Privacy* %s[] = {\n", messageTypeName.c_str());
-    for (int i=0; i<descriptor->field_count(); i++) {
-        const FieldDescriptor* field = descriptor->field(i);
+    printf("Privacy* %s[] = {\n", messageName.c_str());
+    for (size_t i=0; i<fieldsInOrder.size(); i++) {
+        const FieldDescriptor* field = fieldsInOrder[i];
         if (hasDefaultFlags[i]) continue;
         printf("    &%s,\n", getFieldName(field).c_str());
         policyCount++;
@@ -359,29 +417,30 @@
 
     // generates PRIVACY_POLICY_LIST
     printf("// Generate PRIVACY_POLICY_LIST.\n\n");
-    map<string, bool> messageNames;
+    map<string, bool> variableNames;
     set<string> parents;
-    bool skip[descriptor->field_count()];
+    vector<const FieldDescriptor*> fieldsInOrder = sortFields(descriptor);
+    bool skip[fieldsInOrder.size()];
+    const Destination incidentDest = getPrivacyFlags(descriptor).dest();
 
-    for (int i=0; i<descriptor->field_count(); i++) {
-        const FieldDescriptor* field = descriptor->field(i);
+    for (size_t i=0; i<fieldsInOrder.size(); i++) {
+        const FieldDescriptor* field = fieldsInOrder[i];
         const string fieldName = getFieldName(field);
-        PrivacyFlags p = getPrivacyFlags(field);
+        const Destination fieldDest = getFieldDest(field);
+        const string fieldMessageName = getMessageName(field->message_type(), fieldDest);
 
         skip[i] = true;
 
         if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
             continue;
         }
-        // generate privacy flags for each field.
-        if (generatePrivacyFlags(field->message_type(), messageNames, &parents)) {
-            printf("Privacy %s { %d, %d, %s, %d, NULL };\n", fieldName.c_str(), field->number(),
-                    field->type(), getMessageTypeName(field->message_type()).c_str(), p.dest());
-        } else if (isDefaultField(field)) {
+        // generate privacy flags for each section.
+        if (generatePrivacyFlags(field->message_type(), fieldDest, variableNames, &parents)) {
+            printPrivacy(fieldName, field, fieldMessageName, fieldDest, "NULL");
+        } else if (isDefaultField(field, incidentDest)) {
             continue; // don't create a new privacy if the value is default.
         } else {
-            printf("Privacy %s { %d, %d, NULL, %d, NULL };\n", fieldName.c_str(), field->number(),
-                    field->type(), p.dest());
+            printPrivacy(fieldName, field, "NULL", fieldDest, "NULL");
         }
         skip[i] = false;
     }
@@ -391,16 +450,16 @@
     int policyCount = 0;
     if (gSelfRecursionAssignments.empty()) {
         printf("Privacy* privacyArray[] = {\n");
-        for (int i=0; i<descriptor->field_count(); i++) {
+        for (size_t i=0; i<fieldsInOrder.size(); i++) {
             if (skip[i]) continue;
-            printf("    &%s,\n", getFieldName(descriptor->field(i)).c_str());
+            printf("    &%s,\n", getFieldName(fieldsInOrder[i]).c_str());
             policyCount++;
         }
         printf("};\n\n");
         printf("const Privacy** PRIVACY_POLICY_LIST = const_cast<const Privacy**>(privacyArray);\n\n");
         printf("const int PRIVACY_POLICY_COUNT = %d;\n", policyCount);
     } else {
-        for (int i=0; i<descriptor->field_count(); i++) {
+        for (size_t i=0; i<fieldsInOrder.size(); i++) {
             if (!skip[i]) policyCount++;
         }
 
@@ -410,9 +469,9 @@
         }
         printf("    Privacy** privacyArray = (Privacy**)malloc(%d * sizeof(Privacy**));\n", policyCount);
         policyCount = 0; // reset
-        for (int i=0; i<descriptor->field_count(); i++) {
+        for (size_t i=0; i<fieldsInOrder.size(); i++) {
             if (skip[i]) continue;
-            printf("    privacyArray[%d] = &%s;\n", policyCount++, getFieldName(descriptor->field(i)).c_str());
+            printf("    privacyArray[%d] = &%s;\n", policyCount++, getFieldName(fieldsInOrder[i]).c_str());
         }
         printf("    return const_cast<const Privacy**>(privacyArray);\n");
         printf("}\n\n");