1// Copyright 2022 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18	"bufio"
19	"fmt"
20	"io"
21	"os"
22	"strings"
23)
24
25const hashPrefix = "# pg_map_hash: "
26const hashTypePrefix = "SHA-256 "
27const commentPrefix = "#"
28
29// r8Identifier extracts the hash from the comments of a dictionary produced by R8. It returns
30// an empty identifier if no matching comment was found before the first non-comment line.
31func r8Identifier(filename string) (string, error) {
32	f, err := os.Open(filename)
33	if err != nil {
34		return "", fmt.Errorf("failed to open %s: %w", filename, err)
35	}
36	defer f.Close()
37
38	return extractR8CompilerHash(f)
39}
40
41func extractR8CompilerHash(r io.Reader) (string, error) {
42	s := bufio.NewScanner(r)
43	for s.Scan() {
44		line := s.Text()
45		if strings.HasPrefix(line, hashPrefix) {
46			hash := strings.TrimPrefix(line, hashPrefix)
47			if !strings.HasPrefix(hash, hashTypePrefix) {
48				return "", fmt.Errorf("invalid hash type found in %q", line)
49			}
50			return strings.TrimPrefix(hash, hashTypePrefix), nil
51		} else if !strings.HasPrefix(line, commentPrefix) {
52			break
53		}
54	}
55	return "", nil
56}
57