1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.metalava.reporter
18 
19 import java.io.File
20 import java.nio.file.Path
21 
22 /**
23  * Identifies a specific line within an input file.
24  *
25  * The file location is optional as it is not always available. An unavailable source location is
26  * indicated by a null [path]. Even when the [path] is available the [line] may be unknown, which is
27  * indicated by a non-positive value.
28  */
29 abstract class FileLocation {
30     /** The absolute path to the location, or `null` if it could not be found. */
31     abstract val path: Path?
32 
33     /** The line number, may be non-positive indicating that it could not be found. */
34     abstract val line: Int
35 
36     /** The optional [BaselineKey] for the [path]. */
37     open val baselineKey: BaselineKey?
<lambda>null38         get() = path?.let { BaselineKey.forPath(it) }
39 
40     /** Append the string representation of this to the [builder]. */
appendTonull41     fun appendTo(builder: StringBuilder) {
42         builder.append(path)
43         if (line > 0) builder.append(":").append(line)
44     }
45 
toStringnull46     override fun toString() = if (line < 1) path.toString() else "$path:$line"
47 
48     /** A fixed location, known at construction time. */
49     private class FixedFileLocation(
50         override val path: Path?,
51         override val line: Int = 0,
52     ) : FileLocation()
53 
54     companion object {
55         /** The unknown location. */
56         val UNKNOWN: FileLocation = FixedFileLocation(null, 0)
57 
58         /** Create a [FileLocation] for a [path] and optional [line] number. */
59         fun createLocation(path: Path, line: Int = 0): FileLocation = FixedFileLocation(path, line)
60 
61         fun forFile(file: File?): FileLocation {
62             file ?: return UNKNOWN
63             return createLocation(file.toPath(), 0)
64         }
65     }
66 }
67