1# Protocol Buffers - Google's data interchange format
2# Copyright 2008 Google Inc. All rights reserved.
3#
4# Use of this source code is governed by a BSD-style
5# license that can be found in the LICENSE file or at
6# https://developers.google.com/open-source/licenses/bsd
7
8"""Protobuf Runtime versions and validators.
9
10It should only be accessed by Protobuf gencodes and tests. DO NOT USE it
11elsewhere.
12"""
13
14__author__ = 'shaod@google.com (Dennis Shao)'
15
16from enum import Enum
17import os
18import warnings
19
20
21class Domain(Enum):
22 GOOGLE_INTERNAL = 1
23 PUBLIC = 2
24
25
26# The versions of this Python Protobuf runtime to be changed automatically by
27# the Protobuf release process. Do not edit them manually.
28# These OSS versions are not stripped to avoid merging conflicts.
29OSS_DOMAIN = Domain.PUBLIC
30OSS_MAJOR = 5
31OSS_MINOR = 28
32OSS_PATCH = 0
33OSS_SUFFIX = ''
34
35DOMAIN = OSS_DOMAIN
36MAJOR = OSS_MAJOR
37MINOR = OSS_MINOR
38PATCH = OSS_PATCH
39SUFFIX = OSS_SUFFIX
40
41
42class VersionError(Exception):
43 """Exception class for version violation."""
44
45
46def _ReportVersionError(msg):
47 raise VersionError(msg)
48
49
50def ValidateProtobufRuntimeVersion(
51 gen_domain, gen_major, gen_minor, gen_patch, gen_suffix, location
52):
53 """Function to validate versions.
54
55 Args:
56 gen_domain: The domain where the code was generated from.
57 gen_major: The major version number of the gencode.
58 gen_minor: The minor version number of the gencode.
59 gen_patch: The patch version number of the gencode.
60 gen_suffix: The version suffix e.g. '-dev', '-rc1' of the gencode.
61 location: The proto location that causes the version violation.
62
63 Raises:
64 VersionError: if gencode version is invalid or incompatible with the
65 runtime.
66 """
67
68 disable_flag = os.getenv('TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK')
69 if disable_flag is not None and disable_flag.lower() == 'true':
70 return
71
72 version = f'{MAJOR}.{MINOR}.{PATCH}{SUFFIX}'
73 gen_version = f'{gen_major}.{gen_minor}.{gen_patch}{gen_suffix}'
74
75 if gen_major < 0 or gen_minor < 0 or gen_patch < 0:
76 raise VersionError(f'Invalid gencode version: {gen_version}')
77
78 error_prompt = (
79 'See Protobuf version guarantees at'
80 ' https://protobuf.dev/support/cross-version-runtime-guarantee.'
81 )
82
83 if gen_domain != DOMAIN:
84 _ReportVersionError(
85 'Detected mismatched Protobuf Gencode/Runtime domains when loading'
86 f' {location}: gencode {gen_domain.name} runtime {DOMAIN.name}.'
87 ' Cross-domain usage of Protobuf is not supported.'
88 )
89
90 if gen_major != MAJOR:
91 if gen_major == MAJOR - 1:
92 warnings.warn(
93 'Protobuf gencode version %s is exactly one major version older than'
94 ' the runtime version %s at %s. Please update the gencode to avoid'
95 ' compatibility violations in the next runtime release.'
96 % (gen_version, version, location)
97 )
98 else:
99 _ReportVersionError(
100 'Detected mismatched Protobuf Gencode/Runtime major versions when'
101 f' loading {location}: gencode {gen_version} runtime {version}.'
102 f' Same major version is required. {error_prompt}'
103 )
104
105 if MINOR < gen_minor or (MINOR == gen_minor and PATCH < gen_patch):
106 _ReportVersionError(
107 'Detected incompatible Protobuf Gencode/Runtime versions when loading'
108 f' {location}: gencode {gen_version} runtime {version}. Runtime version'
109 f' cannot be older than the linked gencode version. {error_prompt}'
110 )
111 elif MINOR > gen_minor or PATCH > gen_patch:
112 warnings.warn(
113 'Protobuf gencode version %s is older than the runtime version %s at'
114 ' %s. Please avoid checked-in Protobuf gencode that can be obsolete.'
115 % (gen_version, version, location)
116 )
117
118 if gen_suffix != SUFFIX:
119 _ReportVersionError(
120 'Detected mismatched Protobuf Gencode/Runtime version suffixes when'
121 f' loading {location}: gencode {gen_version} runtime {version}.'
122 f' Version suffixes must be the same. {error_prompt}'
123 )