BreakpointComment () { while (i + 1 < len && !(s[i] == '/' && s[i + 1] == '/')) i++; skip('/'); skip('/'); skipWhitespace(); final String head = parseName(); if (i < len && s[i] == '(') { // We have kind with value. comment.kind = head; comment.kindValue = parseValue(); skipWhitespace(); int nameStart = i; String tail = parseName(); if (!tail.equals("Breakpoint")) { throw errorAt(nameStart, "Expected 'Breakpoint' instead of '" + tail + "'"); } } else { var kind = head.replaceFirst("\\s*Breakpoint$", ""); comment.kind = kind.isEmpty() ? "Line" : kind; } skip('!'); while (i < len) { skipWhitespace(); if (i >= len) break; // Allow trailing space. int nameStart = i; String key = parseName(); if (key.isEmpty()) throw errorAt(i, "Expected breakpoint property key"); if (comment.values.containsKey(key)) throw errorAt(nameStart, "Duplicate property key '" + key + "'"); String value = parseValue(); comment.values.put(key, value); comment.index.put(key, nameStart); } skipWhitespace(); if (i < len) throw errorAt(i, "Extra '" + new String(s, i, len - i) + "'"); return comment; }