code: private static long computeMsgIdHelper(
        ImmutableList<SoyMsgPart> msgParts,
        boolean doUseBracedPhs,
        @Nullable String meaning,
        @Nullable String contentType) {
  
      // Important: Do not change this algorithm. Doing so will break backwards compatibility.
  
      String msgContentStrForMsgIdComputation =
          buildMsgContentStrForMsgIdComputation(msgParts, doUseBracedPhs);
  
      long fp = fingerprint(msgContentStrForMsgIdComputation);
  
      // If there is a meaning, incorporate its fingerprint.
      if (meaning != null) {
        fp = (fp << 1) + (fp < 0 ? 1 : 0) + fingerprint(meaning);
      }
  
      // If there is a content type other than "text/html", incorporate its fingerprint.
      if (contentType != null && !contentType.equals("text/html")) {
        fp = (fp << 1) + (fp < 0 ? 1 : 0) + fingerprint(contentType);
      }
  
      // To avoid negative ids we strip the high-order bit.
      return fp & 0x7fffffffffffffffL;
    }
docs: Computes the unique message id for a message, given the message parts, the meaning string (if
  any), and the content type (if any). These are the only elements incorporated into the message
  id.
  
  <p>In particular, note that the id of a message does not change when its desc changes.
  
  @param msgParts The parts of the message.
  @param doUseBracedPhs Whether to use braced placeholders. (Even though braced placeholders
  originated from ICU syntax, the choice of whether to use braced placeholders when computing
  msg id is still a separate decision, even if your message is plural/select and you do use
  ICU syntax to represent plural/select parts.)
  @param meaning The meaning string, or null if none (usually null).
  @param contentType Content type of the document that this message will appear in (e.g. "{@code
  text/html}", or null if not used..