| // Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 | package com.android.tools.r8.utils; | 
 |  | 
 | import java.util.Objects; | 
 |  | 
 | public class SemanticVersion { | 
 |  | 
 |   public static SemanticVersion parse(String version) { | 
 |     int majorEnd = version.indexOf('.'); | 
 |     if (majorEnd <= 0) { | 
 |       throw new IllegalArgumentException("Invalid semantic version: " + version); | 
 |     } | 
 |     int minorEnd = version.indexOf('.', majorEnd + 1); | 
 |     if (minorEnd <= majorEnd + 1) { | 
 |       throw new IllegalArgumentException("Invalid semantic version: " + version); | 
 |     } | 
 |     int patchEnd = version.indexOf('-', minorEnd + 1); | 
 |     int prereleaseEnd = -1; | 
 |     if (patchEnd == -1) { | 
 |       patchEnd = version.length(); | 
 |     } else { | 
 |       if (patchEnd <= minorEnd + 1) { | 
 |         throw new IllegalArgumentException("Invalid semantic version: " + version); | 
 |       } | 
 |       prereleaseEnd = version.length(); | 
 |     } | 
 |     int major; | 
 |     int minor; | 
 |     int patch; | 
 |     String prerelease; | 
 |     try { | 
 |       major = Integer.parseInt(version.substring(0, majorEnd)); | 
 |       minor = Integer.parseInt(version.substring(majorEnd + 1, minorEnd)); | 
 |       patch = Integer.parseInt(version.substring(minorEnd + 1, patchEnd)); | 
 |       prerelease = prereleaseEnd < 0 ? null : version.substring(patchEnd + 1, prereleaseEnd); | 
 |     } catch (NumberFormatException e) { | 
 |       throw new IllegalArgumentException("Invalid semantic version: " + version, e); | 
 |     } | 
 |     return create(major, minor, patch, prerelease); | 
 |   } | 
 |  | 
 |   private final int major; | 
 |   private final int minor; | 
 |   private final int patch; | 
 |   private final String prerelease; | 
 |  | 
 |   private SemanticVersion(int major, int minor, int patch, String prerelease) { | 
 |     this.major = major; | 
 |     this.minor = minor; | 
 |     this.patch = patch; | 
 |     this.prerelease = prerelease; | 
 |   } | 
 |  | 
 |   public static SemanticVersion create(int major, int minor, int patch) { | 
 |     return create(major, minor, patch, null); | 
 |   } | 
 |  | 
 |   public static SemanticVersion create(int major, int minor, int patch, String prerelease) { | 
 |     return new SemanticVersion(major, minor, patch, prerelease); | 
 |   } | 
 |  | 
 |   public int getMajor() { | 
 |     return major; | 
 |   } | 
 |  | 
 |   public int getMinor() { | 
 |     return minor; | 
 |   } | 
 |  | 
 |   public int getPatch() { | 
 |     return patch; | 
 |   } | 
 |  | 
 |   public boolean isNewerOrEqual(SemanticVersion other) { | 
 |     if (major != other.major) { | 
 |       return major > other.major; | 
 |     } | 
 |     if (minor != other.minor) { | 
 |       return minor > other.minor; | 
 |     } | 
 |     return patch >= other.patch; | 
 |   } | 
 |  | 
 |   @Override | 
 |   public boolean equals(Object obj) { | 
 |     if (!(obj instanceof SemanticVersion)) { | 
 |       return false; | 
 |     } | 
 |     SemanticVersion other = (SemanticVersion) obj; | 
 |     return major == other.major | 
 |         && minor == other.minor | 
 |         && patch == other.patch | 
 |         && Objects.equals(prerelease, other.prerelease); | 
 |   } | 
 |  | 
 |   @Override | 
 |   public int hashCode() { | 
 |     return Objects.hash(major, minor, patch, prerelease); | 
 |   } | 
 |  | 
 |   @Override | 
 |   public String toString() { | 
 |     return "" + major + "." + minor + "." + patch + (prerelease != null ? "-" + prerelease : ""); | 
 |   } | 
 | } |